Introduction

Statistical analysis of plasma carotenoids, plasma cytokines and immune cells from randomized cross-over USDA inflammation clinical trial. Subjects consumed both low lycopene tomato (yellow) and high lycopene tomato-soy juices (red) for 4 weeks each.

Crossover clinical trial design supplementing individuals with obesity 360 mL of a low carotenoid tomato juice or a high lycopene tomato-soy juice daily. Daily serving of low carotenoid tomato juice consisted of ~1.5mg lycopene/day while high lycopene tomato-soy juice intervention consisted of 54 mg lycopene/day in addition to 210 mg total soy isoflavones/day.

Crossover clinical trial design supplementing individuals with obesity 360 mL of a low carotenoid tomato juice or a high lycopene tomato-soy juice daily. Daily serving of low carotenoid tomato juice consisted of ~1.5mg lycopene/day while high lycopene tomato-soy juice intervention consisted of 54 mg lycopene/day in addition to 210 mg total soy isoflavones/day.

Load libraries

library(tidyverse) # data wrangling
library(readxl) # read in excel files
library(janitor) # clean up names in dataset
library(corrr) # finding correlations
library(rstatix) # stats
library(knitr) # aesthetic table viewing
library(purrr) # create functions
library(kableExtra)
library(ggthemes)
library(ggtext)
library(ggpubr)
library(ggcorrplot) # to make corr plots
library(pheatmap)

Read in data

# load data
meta_table <- read_excel("CompiledData_Results_Meta.xlsx",
                         sheet = "metadata_corrected_withsequence")

# clean up variable names 
meta_table <- clean_names(meta_table)

str(meta_table)

Wrangle

# convert variables that should be factors to factors
meta_table <- meta_table %>%
  mutate(across(.cols = c("patient_id", "period", 
                          "intervention", "intervention_week", 
                          "pre_post", "sex", "sequence"),
                .fns = as.factor))


# some stuff came in as characters but should be numeric
meta_table <- meta_table %>%
  mutate(across(.cols = c("il_2", "il_10", "il_13", "il_4"),
                .fns = as.numeric))

str(meta_table)
# changing factor levels for pre_post
meta_table$pre_post <- factor(meta_table$pre_post,
                              levels = c("pre", "post"))

levels(meta_table$pre_post)  
## [1] "pre"  "post"
# Calculate total_cis_lyc, total_lyc, and total_carotenoids
meta_table <- meta_table %>%
  rename(n5_cis_lyc = x5_cis_lyc) %>%
  mutate(total_cis_lyc = other_cis_lyc + n5_cis_lyc,
         total_lyc = all_trans_lyc + total_cis_lyc,
         total_carotenoids = lutein + zeaxanthin + b_cryptoxanthin + 
                             a_carotene + b_carotene + total_lyc) 

Carotenoids

All-trans-lyc levels

# line plots for each subject at each timepoint
meta_table %>% 
  ggplot(aes(x = intervention_week, y = all_trans_lyc, color = intervention)) +
  geom_point() + 
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Baseline" = "gray", 
                                           "Yellow" = "gold",
                                           "Red" = "tomato1")) +
  facet_wrap(vars(patient_id), scales = "free_y") + 
  theme_bw() +
  labs(x = "Intervention Week",
       y = "All-trans-lycopene levels (nmol/L)",
       title = "All-trans-lycopene levels in each patient before/after each intervention")

Total cis-lyc levels

# line plots for each subject at each timepoint
meta_table %>% 
  ggplot(aes(x = intervention_week, y = total_cis_lyc, color = intervention)) +
  geom_point() + 
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Baseline" = "gray", 
                                           "Yellow" = "gold",
                                           "Red" = "tomato1")) +
  facet_wrap(vars(patient_id)) +
  theme_bw() +
  labs(x = "Intervention Week",
       y = "Total cis-lycopene levels (nmol/L)",
       title = "Total cis-lycopene levels in each patient before/after each intervention")

Total lyc levels

lineplots

# line plots for each subject at each timepoint
meta_table %>% 
  ggplot(aes(x = intervention_week, y = total_lyc, color = intervention)) +
  geom_point() + 
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Baseline" = "gray", 
                                           "Yellow" = "gold",
                                           "Red" = "tomato1")) +
  facet_wrap(vars(patient_id), scales = "free_y") +
  theme_bw() +
  labs(x = "Intervention Week",
       y = "Total lycopene levels (nmol/L)",
       title = "Total lycopene levels in each patient before/after each intervention")

note Subject 6112 has increased total lycopene levels after yellow intervention. I’ll remove them from statistical analyses.

Boxplots

wrangling

# create a more specific pre_post_intervention column
meta_table_edited <- meta_table %>%
  unite(col = "pre_post_intervention",
        c("pre_post","intervention"),
        sep = "_",
        remove = FALSE)

# make pre_post_intervention column factors
meta_table_edited$pre_post_intervention <- as.factor(meta_table_edited$pre_post_intervention)

# relevel factor columns
meta_table_edited$pre_post_intervention <- factor(meta_table_edited$pre_post_intervention, levels = c("pre_Yellow", "post_Yellow", "pre_Red", "post_Red"))

meta_table_edited$intervention <- factor(meta_table_edited$intervention,
                                         levels = c("Baseline","Yellow", "Red"))
# make legend title
legendtitle_ppintervention <- "Timepoint"


# labels
labs_ppintervention <- c("pre control",
                         "post control",
                         "pre Tomato-Soy",
                         "post Tomato-Soy")

figure

meta_table_edited %>% 
  filter(intervention != "Baseline") %>%
  ggplot(aes(x = intervention, y = total_lyc, fill = pre_post_intervention)) +
  geom_boxplot(outlier.shape = NA) + 
  scale_fill_manual(legendtitle_ppintervention,
                    values = c("pre_Red" = "#FF9966",
                               "post_Red" = "#FF3300",
                               "pre_Yellow" = "#FFFF99",
                               "post_Yellow" = "yellow"),
                    labels = labs_ppintervention) +
  theme_clean() +
  labs(x = "",
       y = "Total lycopene levels (nmol/L)",
       title = "Total lycopene levels before/after juice interventions")

# ggpubr to make pub ready plot
(total_lyc_levels <- meta_table_edited %>% 
    filter(intervention != "Baseline") %>%
  ggpaired(x = "pre_post", y = "total_lyc", fill = "intervention", line.color = "gray", line.size = 1, facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", linewidth = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "nmol/L plasma",
       title = "Concentration of Lycopene",
       subtitle = ""))

export

ggsave(filename = "/Users/mariasholola/Documents/GitHub/USDA-Inflammation-Metabolomics/Plots/total-lyc-red-and-yellow-boxplots.svg", plot = total_lyc_levels, width = 12)

Descriptive stats

wrangle

# convert meta_table_edited to long format for total lycopene
meta_table_lyc_long <- meta_table_edited %>%
  pivot_longer(cols = total_lyc,
               names_to = "total_lycopene",
               values_to = "nmol_per_L")

Avg/std dev

tomsoy
meta_table_lyc_long %>%
  filter(intervention == "Red") %>%
  group_by(pre_post) %>%
  summarize(mean = mean(nmol_per_L),
            stdev = sd(nmol_per_L))
## # A tibble: 2 × 3
##   pre_post  mean stdev
##   <fct>    <dbl> <dbl>
## 1 pre       523.  228.
## 2 post     1298.  665.
yellow
meta_table_lyc_long %>%
  filter(intervention == "Yellow") %>%
  group_by(pre_post) %>%
  summarize(mean = mean(nmol_per_L),
            stdev = sd(nmol_per_L))
## # A tibble: 2 × 3
##   pre_post  mean stdev
##   <fct>    <dbl> <dbl>
## 1 pre       721.  377.
## 2 post      703.  434.

Mean fold changes

lyc_subset <- meta_table_lyc_long %>%
  select(patient_id, pre_post_intervention, nmol_per_L) %>%
  pivot_wider(names_from = pre_post_intervention,
              values_from = nmol_per_L) %>%
  mutate(red_FC = post_Red/pre_Red,
         yellow_FC = post_Yellow/pre_Yellow)

lyc_subset %>%
  summarize(mean_red_FC = mean(red_FC),
            mean_yellow_FC = mean(yellow_FC))
## # A tibble: 1 × 2
##   mean_red_FC mean_yellow_FC
##         <dbl>          <dbl>
## 1        2.83          0.966

Comparison stats

First, I need to remove subject 6112 from the yellow intervention, since their total lycopene levels is the only one increasing post-Yellow

subj6112_yellow <- meta_table_lyc_long %>%
  filter(patient_id == 6112) %>%
  filter(intervention == "Yellow")

meta_table_lyc_long_rm_outlier <- anti_join(meta_table_lyc_long, 
                                            subj6112_yellow)

Normality checks

Plot histogram

gghistogram(meta_table_lyc_long_rm_outlier$nmol_per_L, bins = 40)

Shapiro’s normality test

# shapiro normality test for total lycopene. for pre yellow, post yellow, pre red and post red
meta_table_lyc_long_rm_outlier %>%
  filter(intervention != "Baseline") %>%
  group_by(pre_post_intervention) %>%
  shapiro_test(vars = "nmol_per_L")
## # A tibble: 4 × 4
##   pre_post_intervention variable   statistic      p
##   <fct>                 <chr>          <dbl>  <dbl>
## 1 pre_Yellow            nmol_per_L     0.894 0.157 
## 2 post_Yellow           nmol_per_L     0.861 0.0596
## 3 pre_Red               nmol_per_L     0.962 0.815 
## 4 post_Red              nmol_per_L     0.867 0.0593

P > 0.05 for all 4 groups, suggesting data here is normal.

Paired t-test

compare_means(nmol_per_L ~ pre_post, meta_table_lyc_long_rm_outlier, method = "t.test", paired = TRUE, group.by = "intervention")
## # A tibble: 2 × 9
##   intervention .y.        group2 group1       p  p.adj p.format p.signif method
##   <fct>        <chr>      <chr>  <chr>    <dbl>  <dbl> <chr>    <chr>    <chr> 
## 1 Red          nmol_per_L post   pre    0.00104 0.0021 0.001    **       T-test
## 2 Yellow       nmol_per_L post   pre    0.0934  0.093  0.093    ns       T-test

Boxplot

(lyc_bp_stats_noOutlier <- meta_table_lyc_long_rm_outlier %>% 
   filter(intervention != "Baseline") %>%
  ggpaired(x = "pre_post", y = "nmol_per_L", fill = "intervention", 
           line.color = "gray", 
           line.size = 1, 
           facet.by = "intervention", 
           short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", linewidth = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "nmol/L plasma",
       title = "Concentration of Lycopene",
       subtitle = "") +
   stat_compare_means(method = "t.test", paired = TRUE) )

Total lycopene levels are significantly increasing only after post-Red intervention

export

ggsave(filename = "Plots/total-lyc-red-yellow-boxplots-stats-noOutlier.svg", plot = lyc_bp_stats_noOutlier, width = 12)

Missing data

# calculate how many NAs there are per cytokine in whole data set
containsNAs_cytokines <- meta_table_edited %>%
  filter(intervention != "Baseline") %>%
  pivot_longer(cols = if_ng:il_4,
               names_to = "cytokine",
               values_to = "cyto_conc_pg_ml") %>%
  group_by(cytokine, patient_id) %>%
  count(is.na(cyto_conc_pg_ml)) %>%
  filter(`is.na(cyto_conc_pg_ml)` == TRUE)

kable(containsNAs_cytokines)
cytokine patient_id is.na(cyto_conc_pg_ml) n
il_10 6101 TRUE 1
il_10 6110 TRUE 2
il_13 6103 TRUE 2
il_13 6106 TRUE 3
il_13 6109 TRUE 3
il_13 6111 TRUE 3
il_2 6103 TRUE 3
il_2 6108 TRUE 1
il_2 6109 TRUE 2
il_2 6110 TRUE 4
il_2 6112 TRUE 4
il_4 6101 TRUE 4
il_4 6111 TRUE 4
il_4 6112 TRUE 4
il_4 6113 TRUE 4
# calculate how many NAs there are per cytokine in whole data set
containsNAs_cells <- meta_table_edited %>%
  filter(intervention != "Baseline") %>%
  pivot_longer(cols = starts_with("x"),
               names_to = "cell_type",
               values_to = "cell_value") %>%
  group_by(cell_type, pre_post_intervention) %>%
  count(is.na(cell_value)) %>%
  filter(`is.na(cell_value)` == TRUE)

kable(containsNAs_cells)
cell_type pre_post_intervention is.na(cell_value) n
# impute any missing values by replacing them with 1/2 of the lowest concentration value of a cytokine (i.e. in a row).
imputed_meta_table <- meta_table_edited %>%
  filter(intervention != "Baseline")

imputed_meta_table[,11:25] <- lapply(imputed_meta_table[,11:25], 
                              function(x) ifelse(is.na(x),
                                                 min(x, na.rm = TRUE)/2, x))

dim(imputed_meta_table)
## [1] 48 93

Cytokines

# convert cytokines from wide to long
cytokines_long <- imputed_meta_table[-c(26:82)] %>%
  pivot_longer(cols = if_ng:il_4,
               names_to = "cytokine",
               values_to = "cyto_conc_pg_ml")

Let’s remove subject data points for subject 6112’s yellow intervention first (their total lycopene levels increased post-yellow intervention)

cytokines_noOutlier_long <- anti_join(cytokines_long,
                                      subj6112_yellow)

After testing several mixed linear models, the best model turned out to have pre_post as a fixed variable and patient_id as random effect. Carotenoids added no statistically significant effect to the model, suggesting that carotenoids may not contribute to cytokine levels. We decided to move on with paired mean comparisons for each group. May revisit mixed linear modeling to see if significant metabolites from metabolomics analyses affect immune outcomes (i.e. cytokine concentrations and immune cell populations).

Normality check

cytokines_noOutlier_long %>%
  group_by(cytokine) %>%
  shapiro_test(cyto_conc_pg_ml)
## # A tibble: 15 × 4
##    cytokine variable        statistic        p
##    <chr>    <chr>               <dbl>    <dbl>
##  1 gm_csf   cyto_conc_pg_ml     0.613 8.76e-10
##  2 if_ng    cyto_conc_pg_ml     0.596 4.99e-10
##  3 il_10    cyto_conc_pg_ml     0.736 9.45e- 8
##  4 il_12p40 cyto_conc_pg_ml     0.870 1.08e- 4
##  5 il_12p70 cyto_conc_pg_ml     0.416 2.74e-12
##  6 il_13    cyto_conc_pg_ml     0.691 1.48e- 8
##  7 il_1b    cyto_conc_pg_ml     0.761 2.90e- 7
##  8 il_1ra   cyto_conc_pg_ml     0.699 2.03e- 8
##  9 il_2     cyto_conc_pg_ml     0.552 1.23e-10
## 10 il_4     cyto_conc_pg_ml     0.641 2.29e- 9
## 11 il_5     cyto_conc_pg_ml     0.720 4.82e- 8
## 12 il_6     cyto_conc_pg_ml     0.652 3.42e- 9
## 13 il_8     cyto_conc_pg_ml     0.967 2.09e- 1
## 14 mcp_1    cyto_conc_pg_ml     0.931 9.13e- 3
## 15 tn_fa    cyto_conc_pg_ml     0.676 8.57e- 9

Data is not normally distributed, so will use nonparametric paired tests for the mean comparisons.

Wilcoxon rank-sum tests

Carryover effects?

First, let’s test for sequence effects. We don’t expect to have this problem since the participants did a 4-week washout period (no tomato/lycopene or soy isoflavone-containing foods). This should have been sufficient enough for the intervention to not have lingering effects on cytokine levels.

(wilcox_cyto_seqeffects <- cytokines_long %>%
   filter(pre_post == "post") %>%
   group_by(cytokine) %>%
   wilcox_test(cyto_conc_pg_ml ~ sequence, paired = TRUE, p.adjust.method = "BH", detailed = TRUE))
## # A tibble: 15 × 13
##    cytokine estimate .y.     group1 group2    n1    n2 statistic      p conf.low
##  * <chr>       <dbl> <chr>   <chr>  <chr>  <int> <int>     <dbl>  <dbl>    <dbl>
##  1 gm_csf     11.0   cyto_c… R_Y    Y_R       12    12      52   0.339   -12.1  
##  2 if_ng       0.638 cyto_c… R_Y    Y_R       12    12      59   0.129    -0.815
##  3 il_10      -1.28  cyto_c… R_Y    Y_R       12    12      15   0.12     -4.49 
##  4 il_12p40   -1.92  cyto_c… R_Y    Y_R       12    12      37   0.91    -33.9  
##  5 il_12p70    0.19  cyto_c… R_Y    Y_R       12    12      43   0.791    -1.66 
##  6 il_13      18.3   cyto_c… R_Y    Y_R       12    12      50   0.142    -4.31 
##  7 il_1b       3.09  cyto_c… R_Y    Y_R       12    12      49   0.47    -16.6  
##  8 il_1ra      0.728 cyto_c… R_Y    Y_R       12    12      48   0.519    -1.07 
##  9 il_2        0.682 cyto_c… R_Y    Y_R       12    12      40.5 0.533    -0.910
## 10 il_4        0.210 cyto_c… R_Y    Y_R       12    12      33   0.61     -2.15 
## 11 il_5       -1.19  cyto_c… R_Y    Y_R       12    12      31   0.569    -4.70 
## 12 il_6        0.832 cyto_c… R_Y    Y_R       12    12      56.5 0.182    -0.435
## 13 il_8       -0.538 cyto_c… R_Y    Y_R       12    12      29   0.47     -1.90 
## 14 mcp_1     -32.5   cyto_c… R_Y    Y_R       12    12      17   0.0923 -107.   
## 15 tn_fa       4.97  cyto_c… R_Y    Y_R       12    12      42   0.85     -8.93 
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>

For every cytokine, sequence does not significantly effect the outcome. Therefore we can continue to assume there are no sequence effects.

Friedman test

Non-parametric alternative to repeated measures ANOVA

#not working for me
friedman_test <- cytokines_long %>%
  select(patient_id, pre_post_intervention, cytokine, cyto_conc_pg_ml) %>%
  friedman_test(cyto_conc_pg_ml ~ pre_post_intervention | patient_id)

Yellow trt effects

Comparing pre- to post-yellow (low carotenoid) intervention

(wilcox_cyto_yellow <- cytokines_noOutlier_long %>%
  filter(intervention == "Yellow") %>%
  group_by(cytokine) %>%
  wilcox_test(cyto_conc_pg_ml ~ pre_post, paired = TRUE, p.adjust.method = "BH", detailed = TRUE))
## # A tibble: 15 × 13
##    cytokine   estimate .y.    group1 group2    n1    n2 statistic     p conf.low
##  * <chr>         <dbl> <chr>  <chr>  <chr>  <int> <int>     <dbl> <dbl>    <dbl>
##  1 gm_csf    1.02      cyto_… pre    post      11    11      42   0.465  -2.41  
##  2 if_ng     0.0375    cyto_… pre    post      11    11      41   0.52   -0.075 
##  3 il_10    -0.0325    cyto_… pre    post      11    11      32   0.966  -0.310 
##  4 il_12p40  1.18      cyto_… pre    post      11    11      29   0.919  -9.23  
##  5 il_12p70 -0.110     cyto_… pre    post      11    11      24   0.76   -0.340 
##  6 il_13    -0.0000123 cyto_… pre    post      11    11      22.5 1      -1.96  
##  7 il_1b     3.73      cyto_… pre    post      11    11      34   0.193  -0.965 
##  8 il_1ra    0.348     cyto_… pre    post      11    11      49   0.175  -0.340 
##  9 il_2      0.285     cyto_… pre    post      11    11      34   0.193  -0.0950
## 10 il_4      0.0535    cyto_… pre    post      11    11      28   0.183  -0.0400
## 11 il_5     -0.538     cyto_… pre    post      11    11      25   0.52   -2.01  
## 12 il_6      0.868     cyto_… pre    post      11    11      46   0.278  -0.805 
## 13 il_8     -0.178     cyto_… pre    post      11    11      27   0.638  -0.94  
## 14 mcp_1    -1.72      cyto_… pre    post      11    11      27   0.638 -16.2   
## 15 tn_fa    -0.373     cyto_… pre    post      11    11      32   0.966  -2.93  
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>
# extract statistically significant cytokines 
(sig_cytokines_yellow <- wilcox_cyto_yellow %>%
  filter(p < 0.05))
## # A tibble: 0 × 13
## # ℹ 13 variables: cytokine <chr>, estimate <dbl>, .y. <chr>, group1 <chr>,
## #   group2 <chr>, n1 <int>, n2 <int>, statistic <dbl>, p <dbl>, conf.low <dbl>,
## #   conf.high <dbl>, method <chr>, alternative <chr>

Red trt effects

Comparing pre- to post-red (tomato-soy) intervention

(wilcox_cyto_red <-  cytokines_noOutlier_long %>%
  filter(intervention == "Red") %>%
  group_by(cytokine) %>%
  wilcox_test(cyto_conc_pg_ml ~ pre_post, paired = TRUE, p.adjust.method = "BH", detailed = TRUE))
## # A tibble: 15 × 13
##    cytokine estimate .y.     group1 group2    n1    n2 statistic      p conf.low
##  * <chr>       <dbl> <chr>   <chr>  <chr>  <int> <int>     <dbl>  <dbl>    <dbl>
##  1 gm_csf     2.20   cyto_c… pre    post      12    12      65   0.0425   0.0350
##  2 if_ng      0.145  cyto_c… pre    post      12    12      49   0.168   -0.0750
##  3 il_10      0.148  cyto_c… pre    post      12    12      51   0.38    -0.12  
##  4 il_12p40  10.0    cyto_c… pre    post      12    12      61   0.0923  -2.34  
##  5 il_12p70   0.672  cyto_c… pre    post      12    12      66   0.0376   0.0401
##  6 il_13      1.67   cyto_c… pre    post      12    12      47   0.23    -1.28  
##  7 il_1b      0.986  cyto_c… pre    post      12    12      48   0.197   -0.535 
##  8 il_1ra     0.115  cyto_c… pre    post      12    12      44   0.733   -0.405 
##  9 il_2       0.170  cyto_c… pre    post      12    12      31   0.343   -0.120 
## 10 il_4       0.0922 cyto_c… pre    post      12    12      26   0.294   -0.100 
## 11 il_5       0.958  cyto_c… pre    post      12    12      65   0.0425   0.0300
## 12 il_6       0.375  cyto_c… pre    post      12    12      57   0.176   -0.165 
## 13 il_8      -0.0765 cyto_c… pre    post      12    12      31.5 0.583   -0.450 
## 14 mcp_1     -0.875  cyto_c… pre    post      12    12      38   0.97   -12.5   
## 15 tn_fa      2.72   cyto_c… pre    post      12    12      64   0.0522  -0.25  
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>
# extract statistically significant cytokines 
(sig_cytokines_red <- wilcox_cyto_red %>%
  filter(wilcox_cyto_red$p < 0.05))
## # A tibble: 3 × 13
##   cytokine estimate .y.      group1 group2    n1    n2 statistic      p conf.low
##   <chr>       <dbl> <chr>    <chr>  <chr>  <int> <int>     <dbl>  <dbl>    <dbl>
## 1 gm_csf      2.20  cyto_co… pre    post      12    12        65 0.0425   0.0350
## 2 il_12p70    0.672 cyto_co… pre    post      12    12        66 0.0376   0.0401
## 3 il_5        0.958 cyto_co… pre    post      12    12        65 0.0425   0.0300
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>
  • There are 3 cytokines (GM-CSF, IL-12p70, and IL-5) significantly different between pre and post-Red interventions only. Lets investigate.

GM-CSF

boxplots
cytokines_long %>% 
  filter(cytokine == "gm_csf") %>%
  ggpaired(x = "pre_post", y = "cyto_conc_pg_ml", fill = "intervention", facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "pg/mL plasma",
       title = "Concentration of GM-CSF",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

cytokines_long %>% 
  filter(cytokine == "gm_csf") %>%
  filter(patient_id != 6102) %>% #6102 has really high levels so let's see what the data looks like without them
  ggpaired(x = "pre_post", y = "cyto_conc_pg_ml", fill = "intervention", facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "pg/mL plasma",
       title = "Concentration of GM-CSF",
       subtitle = "")

lineplots
meta_table %>% 
  filter(intervention != "Baseline") %>%
  ggplot(aes(x = pre_post, y = gm_csf, color = intervention)) +
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Yellow" = "gold",
                                "Red" = "tomato1")) +
  facet_wrap(vars(patient_id), scales = "free_y") + 
  theme_classic() +
  labs(x = "",
       y = "GM-CSF conc (pg/mL)",
       title = "GM-CSF levels in each patient pre- and post- red and yellow intervention")

IL-12p70

boxplots
cytokines_long %>% 
  filter(cytokine == "il_12p70") %>%
  ggpaired(x = "pre_post", y = "cyto_conc_pg_ml", fill = "intervention", facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "pg/mL plasma",
       title = "Concentration of IL-12p70",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

cytokines_long %>% 
  filter(cytokine == "il_12p70") %>%
  filter(patient_id != 6102) %>% # take off subject 6102 since their levels are so high
  ggpaired(x = "pre_post", y = "cyto_conc_pg_ml", fill = "intervention", facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "pg/mL plasma",
       title = "Concentration of IL-12p70",
       subtitle = "")

lineplots
meta_table %>% 
  filter(intervention != "Baseline") %>%
  ggplot(aes(x = pre_post, y = il_12p70, color = intervention)) +
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Yellow" = "gold",
                                "Red" = "tomato1")) +
  facet_wrap(vars(patient_id), scales = "free_y") + 
  theme_classic() +
  labs(x = "",
       y = "IL-12p70 conc (pg/mL)",
       title = "IL-12p70 levels in each patient pre- and post- red and yellow intervention")

IL-5

boxplots
cytokines_long %>% 
  filter(cytokine == "il_5") %>%
  filter(intervention != "Baseline") %>%
  ggpaired(x = "pre_post", y = "cyto_conc_pg_ml", fill = "intervention", facet.by = "intervention", short.panel.labs = FALSE, panel.labs = list(intervention = c("", "", ""))) +
  scale_fill_manual(values = c("Red" = "tomato1",
                               "Yellow" = "yellow1"),
                    labels = c("Control", "Tomato-Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "pg/mL plasma",
       title = "Concentration of IL-5",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

lineplots
meta_table %>% 
  filter(intervention != "Baseline") %>%
  ggplot(aes(x = pre_post, y = il_5, color = intervention)) +
  geom_line(aes(group = intervention)) +
  scale_color_manual(values = c("Yellow" = "gold",
                                "Red" = "tomato1")) +
  facet_wrap(vars(patient_id), scales = "free_y") + 
  theme_classic() +
  labs(x = "",
       y = "IL-5 conc (pg/mL)",
       title = "IL-5 levels in each patient pre- and post- red and yellow intervention")

fold change

Let’s look at the average fold change for significantly changing cells in yellow. We’ll look at the avg fold change comparing pre to post yellow, pre to post Red, and post-intervention comparison.

red_sigcytokines_subset <- cytokines_noOutlier_long %>%
  filter(cytokine %in% sig_cytokines_red$cytokine)%>%
  select(patient_id, pre_post_intervention, cytokine, cyto_conc_pg_ml) %>%
  group_by(cytokine) %>%
  pivot_wider(names_from = pre_post_intervention,
              values_from = cyto_conc_pg_ml) %>%
  mutate(yellow_FC = post_Yellow/pre_Yellow,
         red_FC = post_Red/pre_Red,
         post_intervention_FC = post_Red/post_Yellow)

red_sigcytokines_subset %>%
  summarize(mean_yellow_FC = mean(yellow_FC, na.rm = TRUE),
            mean_red_FC = mean(red_FC),
            mean_intervention_FC = mean(post_intervention_FC, na.rm = TRUE))
## # A tibble: 3 × 4
##   cytokine mean_yellow_FC mean_red_FC mean_intervention_FC
##   <chr>             <dbl>       <dbl>                <dbl>
## 1 gm_csf            0.954       0.830                0.916
## 2 il_12p70          1.02        0.735                0.916
## 3 il_5              1.32        0.828                0.817

Intervention comparison

(wilcox_cyto_intervention <- cytokines_noOutlier_long %>%
  filter(patient_id != 6112) %>% # remove subject 6112 so the red vs yellow comparison is even
  filter(pre_post == "post") %>%
  group_by(cytokine) %>%
  wilcox_test(cyto_conc_pg_ml ~ pre_post_intervention, paired = TRUE, p.adjust.method = "BH", detailed = TRUE))
## # A tibble: 15 × 13
##    cytokine estimate .y.      group1 group2    n1    n2 statistic     p conf.low
##  * <chr>       <dbl> <chr>    <chr>  <chr>  <int> <int>     <dbl> <dbl>    <dbl>
##  1 gm_csf   -2.37    cyto_co… post_… post_…    11    11        30 0.831   -38.4 
##  2 if_ng    -0.122   cyto_co… post_… post_…    11    11        30 0.831    -1.6 
##  3 il_10     0.193   cyto_co… post_… post_…    11    11        35 0.898    -2.51
##  4 il_12p40  2.99    cyto_co… post_… post_…    11    11        39 0.638   -35.8 
##  5 il_12p70  0.46    cyto_co… post_… post_…    11    11        40 0.577    -6   
##  6 il_13    -0.715   cyto_co… post_… post_…    11    11        27 1       -27.8 
##  7 il_1b     0.885   cyto_co… post_… post_…    11    11        35 0.898   -11.6 
##  8 il_1ra    0.64    cyto_co… post_… post_…    11    11        40 0.577    -1.78
##  9 il_2     -0.00998 cyto_co… post_… post_…    11    11        27 1        -1.96
## 10 il_4     -0.0513  cyto_co… post_… post_…    11    11        30 0.831    -1.84
## 11 il_5      1.34    cyto_co… post_… post_…    11    11        44 0.365    -3.29
## 12 il_6      0.788   cyto_co… post_… post_…    11    11        47 0.24     -0.98
## 13 il_8     -0.0150  cyto_co… post_… post_…    11    11        33 1        -1.08
## 14 mcp_1    -2.36    cyto_co… post_… post_…    11    11        32 0.966   -50.3 
## 15 tn_fa     1.12    cyto_co… post_… post_…    11    11        36 0.831   -11.0 
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>
# extract statistically significant cytokines 
(sig_cytokines_intervention <- wilcox_cyto_intervention %>%
  filter(p < 0.05))
## # A tibble: 0 × 13
## # ℹ 13 variables: cytokine <chr>, estimate <dbl>, .y. <chr>, group1 <chr>,
## #   group2 <chr>, n1 <int>, n2 <int>, statistic <dbl>, p <dbl>, conf.low <dbl>,
## #   conf.high <dbl>, method <chr>, alternative <chr>

Immune Cells

# convert immune cell data from wide to long
cells_long <- imputed_meta_table %>%
  pivot_longer(cols = starts_with("x"),
               names_to = "cell_type",
               values_to = "cell_value")

Let’s remove subject data points for subject 6112’s yellow intervention first (their total lycopene levels increased post-yellow intervention)

cells_noOutlier_long <- anti_join(cells_long,
                                  subj6112_yellow)

After testing several mixed linear models, the best model turned out to have pre_post as a fixed variable and patient_id as random effect. Carotenoids added no statistically significant effect to the model, suggesting that carotenoids are not contributing to cytokine levels. We decided to move on with paired mean comparisons for each group. May revisit mixed linear modeling to see if significant metabolites from metabolomics analyses affect immune outcomes (i.e. cytokine concentrations and immune cell populations).

Normality check

cells_noOutlier_long %>%
  group_by(cell_type) %>%
  shapiro_test(cell_value)
## # A tibble: 39 × 4
##    cell_type                    variable   statistic            p
##    <chr>                        <chr>          <dbl>        <dbl>
##  1 x01_cd45_cd66b_lymph_dc_mono cell_value     0.718 0.0000000282
##  2 x02_cd45_cd66b_grans         cell_value     0.693 0.0000000102
##  3 x03_cd3_cd45_cd3_t_cells     cell_value     0.964 0.144       
##  4 x04_tc_rgd_cd3_ab_t_cells    cell_value     0.965 0.161       
##  5 x05_cd4_cd8_cd8_t_cells      cell_value     0.926 0.00490     
##  6 x06_cd45ro_cd45ra_naive_cd8  cell_value     0.878 0.000135    
##  7 x07_cd46ro_cd45ra_cm_cd8     cell_value     0.880 0.000151    
##  8 x08_cd45ro_cd45ra_em_cd8     cell_value     0.892 0.000354    
##  9 x09_cd45r0_cd45ra_te_cd8     cell_value     0.854 0.0000287   
## 10 x10_cd38_hladr_activated_cd8 cell_value     0.960 0.106       
## # ℹ 29 more rows

Data is not normally distributed for several cell types, so it will be more appropriate use nonparametric paired tests for the mean comparisons.

Wilcoxon rank-sum tests

Carryover effects?

First, let’s test for sequence effects. We don’t expect to have this problem since the participants did a 4-week washout period (no tomato/lycopene or soy isoflavone-containing foods). This should have been sufficient enough for the intervention to not have lingering effects on cell populations.

wilcox_cells_seqeffects <- cells_long %>%
   filter(pre_post == "post") %>%
   group_by(cell_type) %>%
   wilcox_test(cell_value ~ sequence, paired = TRUE, p.adjust.method = "BH", detailed = TRUE)

kable(wilcox_cells_seqeffects, format = "markdown", digits = 3)
cell_type estimate .y. group1 group2 n1 n2 statistic p conf.low conf.high method alternative
x01_cd45_cd66b_lymph_dc_mono 0.749 cell_value R_Y Y_R 12 12 46 0.622 -1.927 3.530 Wilcoxon two.sided
x02_cd45_cd66b_grans 0.104 cell_value R_Y Y_R 12 12 48 0.519 -1.184 0.451 Wilcoxon two.sided
x03_cd3_cd45_cd3_t_cells 0.547 cell_value R_Y Y_R 12 12 39 1.000 -10.730 10.298 Wilcoxon two.sided
x04_tc_rgd_cd3_ab_t_cells 0.852 cell_value R_Y Y_R 12 12 40 0.970 -9.714 10.626 Wilcoxon two.sided
x05_cd4_cd8_cd8_t_cells -3.533 cell_value R_Y Y_R 12 12 20 0.151 -10.151 3.026 Wilcoxon two.sided
x06_cd45ro_cd45ra_naive_cd8 -0.648 cell_value R_Y Y_R 12 12 33 0.677 -4.287 2.635 Wilcoxon two.sided
x07_cd46ro_cd45ra_cm_cd8 -0.092 cell_value R_Y Y_R 12 12 30 0.519 -0.297 0.153 Wilcoxon two.sided
x08_cd45ro_cd45ra_em_cd8 -1.191 cell_value R_Y Y_R 12 12 28 0.424 -4.496 1.720 Wilcoxon two.sided
x09_cd45r0_cd45ra_te_cd8 -0.080 cell_value R_Y Y_R 12 12 37 0.910 -0.892 0.969 Wilcoxon two.sided
x10_cd38_hladr_activated_cd8 -0.020 cell_value R_Y Y_R 12 12 30 0.519 -0.072 0.035 Wilcoxon two.sided
x11_cd4_cd8_cd4_t_cells 2.972 cell_value R_Y Y_R 12 12 49 0.470 -6.548 13.344 Wilcoxon two.sided
x12_cd45ro_cd45ra_naive_cd4 -0.139 cell_value R_Y Y_R 12 12 38 0.970 -6.918 6.436 Wilcoxon two.sided
x13_cd45ro_cd45ra_cm_cd4 -0.582 cell_value R_Y Y_R 12 12 32 0.622 -2.699 8.300 Wilcoxon two.sided
x14_cd45ro_cd45ra -0.957 cell_value R_Y Y_R 12 12 20 0.151 -2.246 0.572 Wilcoxon two.sided
x15_cd45ro_cd45ra_te_cd4 -0.223 cell_value R_Y Y_R 12 12 24 0.266 -0.497 0.246 Wilcoxon two.sided
x16_cd38_hladr_activated_cd4 -0.027 cell_value R_Y Y_R 12 12 32 0.622 -0.234 0.178 Wilcoxon two.sided
x17_cd25_cd127_tregs -0.137 cell_value R_Y Y_R 12 12 25 0.301 -0.764 0.089 Wilcoxon two.sided
x18_ccr4_cd4_total_ccr4_treg -0.214 cell_value R_Y Y_R 12 12 18 0.110 -0.769 0.049 Wilcoxon two.sided
x19_cd45ra_cd45ro_ccr4_treg_naive -0.019 cell_value R_Y Y_R 12 12 11 0.027 -0.041 -0.003 Wilcoxon two.sided
x20_hladr_total_ccr4_treg_activated -0.048 cell_value R_Y Y_R 12 12 33 0.677 -0.149 0.105 Wilcoxon two.sided
x21_cd45ra_cd45ro_ccr4_treg_memory -0.130 cell_value R_Y Y_R 12 12 23 0.233 -0.616 0.081 Wilcoxon two.sided
x22_cxcr3_ccr6_th1 -0.975 cell_value R_Y Y_R 12 12 18 0.110 -1.831 0.377 Wilcoxon two.sided
x23_cxcr3_ccr6_th2 -2.984 cell_value R_Y Y_R 12 12 29 0.470 -10.986 3.824 Wilcoxon two.sided
x24_cxcr3_ccr6_th17 -2.054 cell_value R_Y Y_R 12 12 34 0.733 -4.400 7.155 Wilcoxon two.sided
x25_cd19_cd3_b_cells 1.007 cell_value R_Y Y_R 12 12 46 0.622 -4.840 2.912 Wilcoxon two.sided
x26_cd27_ig_d_naive_b_cells 0.299 cell_value R_Y Y_R 12 12 41 0.910 -5.320 2.972 Wilcoxon two.sided
x27_cd27_ig_d_memory_b_cells 0.335 cell_value R_Y Y_R 12 12 59 0.129 -0.217 0.872 Wilcoxon two.sided
x28_cd27_ig_d_memory_resting_b_cells 0.024 cell_value R_Y Y_R 12 12 42 0.850 -0.165 0.546 Wilcoxon two.sided
x30_cd27_cd38_plasmablasts 0.017 cell_value R_Y Y_R 12 12 51 0.380 -0.009 0.066 Wilcoxon two.sided
x31_cd14_monocytes 1.619 cell_value R_Y Y_R 12 12 45 0.677 -6.241 12.224 Wilcoxon two.sided
x32_cd16_non_classical_mono 0.171 cell_value R_Y Y_R 12 12 46 0.622 -0.467 0.805 Wilcoxon two.sided
x33_cd16_classical_mono 0.189 cell_value R_Y Y_R 12 12 44 0.733 -7.760 11.174 Wilcoxon two.sided
x34_hladr_cd56 1.477 cell_value R_Y Y_R 12 12 42 0.850 -5.279 9.547 Wilcoxon two.sided
x35_cd16_cd123_cd11c_p_dc 0.020 cell_value R_Y Y_R 12 12 45 0.677 -0.093 0.169 Wilcoxon two.sided
x36_cd16_cd123_cd11c_m_dc 0.570 cell_value R_Y Y_R 12 12 40 0.970 -7.313 9.070 Wilcoxon two.sided
x37_cd56_cd161_cd123_nk_cells 0.975 cell_value R_Y Y_R 12 12 45 0.677 -3.287 6.313 Wilcoxon two.sided
x38_cd16_nk_cells -0.376 cell_value R_Y Y_R 12 12 36 0.850 -3.960 2.063 Wilcoxon two.sided
x40_cd14_mdsc_mono 0.522 cell_value R_Y Y_R 12 12 43 0.791 -5.934 14.504 Wilcoxon two.sided
x41_cd66b_mdsc_grans 0.013 cell_value R_Y Y_R 12 12 41 0.910 -0.219 0.314 Wilcoxon two.sided
# extract statistically significant cytokines 
wilcox_cells_seqeffects %>%
  filter(p < 0.05)
## # A tibble: 1 × 13
##   cell_type   estimate .y.   group1 group2    n1    n2 statistic      p conf.low
##   <chr>          <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>  <dbl>    <dbl>
## 1 x19_cd45ra…  -0.0193 cell… R_Y    Y_R       12    12        11 0.0269  -0.0409
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>

Seems to be sequence effects for cell type #19. We will keep this in mind for the rest of the analyses.

Yellow trt effects

Comparing pre- to post-yellow (low carotenoid) intervention

wilcox_cells_yellow <- cells_noOutlier_long %>%
  filter(intervention == "Yellow") %>%
  group_by(cell_type) %>%
  wilcox_test(cell_value ~ pre_post, paired = TRUE, p.adjust.method = "BH", detailed = TRUE)

kable(wilcox_cells_yellow, format = "markdown", digits = 3)
cell_type estimate .y. group1 group2 n1 n2 statistic p conf.low conf.high method alternative
x01_cd45_cd66b_lymph_dc_mono -0.020 cell_value pre post 12 12 39 1.000 -2.423 1.338 Wilcoxon two.sided
x02_cd45_cd66b_grans 0.157 cell_value pre post 12 12 57 0.176 -0.044 0.609 Wilcoxon two.sided
x03_cd3_cd45_cd3_t_cells 0.059 cell_value pre post 12 12 39 1.000 -10.501 10.828 Wilcoxon two.sided
x04_tc_rgd_cd3_ab_t_cells 0.458 cell_value pre post 12 12 42 0.850 -10.329 11.068 Wilcoxon two.sided
x05_cd4_cd8_cd8_t_cells -1.858 cell_value pre post 12 12 6 0.007 -3.930 -0.853 Wilcoxon two.sided
x06_cd45ro_cd45ra_naive_cd8 -0.179 cell_value pre post 12 12 35 0.791 -1.146 1.083 Wilcoxon two.sided
x07_cd46ro_cd45ra_cm_cd8 0.058 cell_value pre post 12 12 45 0.677 -0.128 0.298 Wilcoxon two.sided
x08_cd45ro_cd45ra_em_cd8 -1.252 cell_value pre post 12 12 0 0.000 -1.989 -0.695 Wilcoxon two.sided
x09_cd45r0_cd45ra_te_cd8 -0.396 cell_value pre post 12 12 13 0.043 -0.887 -0.033 Wilcoxon two.sided
x10_cd38_hladr_activated_cd8 -0.018 cell_value pre post 12 12 31 0.569 -0.050 0.023 Wilcoxon two.sided
x11_cd4_cd8_cd4_t_cells 3.011 cell_value pre post 12 12 49 0.470 -5.959 11.409 Wilcoxon two.sided
x12_cd45ro_cd45ra_naive_cd4 1.816 cell_value pre post 12 12 52 0.339 -2.224 6.323 Wilcoxon two.sided
x13_cd45ro_cd45ra_cm_cd4 1.004 cell_value pre post 12 12 48 0.519 -1.876 3.551 Wilcoxon two.sided
x14_cd45ro_cd45ra -0.444 cell_value pre post 12 12 17 0.092 -0.974 0.182 Wilcoxon two.sided
x15_cd45ro_cd45ra_te_cd4 -0.072 cell_value pre post 12 12 0 0.000 -0.157 -0.022 Wilcoxon two.sided
x16_cd38_hladr_activated_cd4 -0.039 cell_value pre post 12 12 26 0.339 -0.110 0.045 Wilcoxon two.sided
x17_cd25_cd127_tregs -0.039 cell_value pre post 12 12 34 0.733 -0.193 0.183 Wilcoxon two.sided
x18_ccr4_cd4_total_ccr4_treg -0.055 cell_value pre post 12 12 29 0.470 -0.184 0.125 Wilcoxon two.sided
x19_cd45ra_cd45ro_ccr4_treg_naive -0.005 cell_value pre post 12 12 24 0.266 -0.017 0.005 Wilcoxon two.sided
x20_hladr_total_ccr4_treg_activated -0.039 cell_value pre post 12 12 25 0.301 -0.107 0.073 Wilcoxon two.sided
x21_cd45ra_cd45ro_ccr4_treg_memory -0.043 cell_value pre post 12 12 31 0.569 -0.158 0.123 Wilcoxon two.sided
x22_cxcr3_ccr6_th1 0.308 cell_value pre post 12 12 49 0.470 -0.481 1.096 Wilcoxon two.sided
x23_cxcr3_ccr6_th2 2.739 cell_value pre post 12 12 53 0.301 -4.335 10.332 Wilcoxon two.sided
x24_cxcr3_ccr6_th17 -0.330 cell_value pre post 12 12 28 0.424 -4.462 0.484 Wilcoxon two.sided
x25_cd19_cd3_b_cells -2.358 cell_value pre post 12 12 15 0.064 -4.879 0.343 Wilcoxon two.sided
x26_cd27_ig_d_naive_b_cells -2.076 cell_value pre post 12 12 11 0.027 -3.807 -0.062 Wilcoxon two.sided
x27_cd27_ig_d_memory_b_cells -0.156 cell_value pre post 12 12 24 0.266 -0.472 0.469 Wilcoxon two.sided
x28_cd27_ig_d_memory_resting_b_cells 0.045 cell_value pre post 12 12 48 0.519 -0.073 0.225 Wilcoxon two.sided
x30_cd27_cd38_plasmablasts -0.001 cell_value pre post 12 12 36 0.850 -0.038 0.015 Wilcoxon two.sided
x31_cd14_monocytes 1.384 cell_value pre post 12 12 46 0.622 -4.459 8.364 Wilcoxon two.sided
x32_cd16_non_classical_mono 0.496 cell_value pre post 12 12 54 0.266 -0.374 1.772 Wilcoxon two.sided
x33_cd16_classical_mono 0.035 cell_value pre post 12 12 39 1.000 -3.616 7.042 Wilcoxon two.sided
x34_hladr_cd56 0.578 cell_value pre post 12 12 40 0.970 -4.647 6.576 Wilcoxon two.sided
x35_cd16_cd123_cd11c_p_dc -0.010 cell_value pre post 12 12 35 0.791 -0.094 0.073 Wilcoxon two.sided
x36_cd16_cd123_cd11c_m_dc 0.346 cell_value pre post 12 12 42 0.850 -3.829 6.239 Wilcoxon two.sided
x37_cd56_cd161_cd123_nk_cells -0.565 cell_value pre post 12 12 5 0.005 -1.385 -0.172 Wilcoxon two.sided
x38_cd16_nk_cells 0.169 cell_value pre post 12 12 41 0.910 -1.645 4.287 Wilcoxon two.sided
x40_cd14_mdsc_mono 0.051 cell_value pre post 12 12 53 0.301 -0.049 0.219 Wilcoxon two.sided
x41_cd66b_mdsc_grans 0.022 cell_value pre post 12 12 54 0.266 -0.017 0.119 Wilcoxon two.sided
# extract statistically significant cytokines 
(sig_cells_yellow <- wilcox_cells_yellow %>%
  filter(p < 0.05))
## # A tibble: 6 × 13
##   cell_type  estimate .y.   group1 group2    n1    n2 statistic       p conf.low
##   <chr>         <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>   <dbl>    <dbl>
## 1 x05_cd4_c…  -1.86   cell… pre    post      12    12         6 6.84e-3   -3.93 
## 2 x08_cd45r…  -1.25   cell… pre    post      12    12         0 4.88e-4   -1.99 
## 3 x09_cd45r…  -0.396  cell… pre    post      12    12        13 4.25e-2   -0.887
## 4 x15_cd45r…  -0.0723 cell… pre    post      12    12         0 4.88e-4   -0.157
## 5 x26_cd27_…  -2.08   cell… pre    post      12    12        11 2.69e-2   -3.81 
## 6 x37_cd56_…  -0.565  cell… pre    post      12    12         5 4.88e-3   -1.38 
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>

Sig cells

boxplots
(sigcells_yellow_bp <- cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_yellow$cell_type) %>%
  filter(intervention == "Yellow") %>%
  ggpaired(x = "pre_post", y = "cell_value", fill = "intervention", facet.by = c("cell_type")) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Control"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell percentage",
       title = "Cell populations significantly different between pre- and post-Yellow",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH"))

Log2 the scale so change is more visible

cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_yellow$cell_type) %>%
  filter(intervention == "Yellow") %>%
   mutate(log2_cellvalue = log2(cell_value)) %>%
  ggpaired(x = "pre_post", y = "log2_cellvalue", fill = "intervention", facet.by = c("cell_type")) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Control"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Log2 cell %",
       title = "Cell populations significantly different between pre- and post-Yellow",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

Let’s see what things look like in red intervention

cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_yellow$cell_type) %>%
  mutate(log2_cellvalue = log2(cell_value)) %>%
  filter(intervention == "Red") %>%
  ggpaired(x = "pre_post", y = "log2_cellvalue", fill = "intervention", facet.by = c("cell_type")) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Tomato Soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Log2 cell %",
       title = "Cell populations significantly different between pre- and post-Yellow",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

Cell #26 (Naive B-cell) is significantly increased after both interventions, although post-red has a stronger significance.

lineplots

To get a sense of cell population percentages on the individual basis, we’ll look at line graphs.

I’m going to make a function for this for this first.

# function for line plots
line_plots_cells_fx <- function(immune_cell) {
  cells_long %>% # even though this subject 6112 wasnt included for yellow stats, I'll still include them for the plots
    filter(cell_type == immune_cell) %>%
    ggplot(aes(x = pre_post, y = cell_value, color = intervention)) +
    geom_line(aes(group = intervention)) +
    scale_color_manual(values = c("Yellow" = "gold",
                                "Red" = "tomato1")) +
    facet_wrap(vars(patient_id), scales = "free_y") + 
    theme_classic() +
    labs(x = "",
         y = "Cell population (%)",
         title = paste(immune_cell, "in each patient pre- and post- red and yellow intervention"))
}
# create list for plots
lineplots_cells <- list()

# run this function on all cell types
for (i in cells_noOutlier_long$cell_type) {
  lineplots_cells[[i]] = line_plots_cells_fx(i)
}
# signif immune cells pre vs post yellow
sig_cells_yellow$cell_type
## [1] "x05_cd4_cd8_cd8_t_cells"       "x08_cd45ro_cd45ra_em_cd8"     
## [3] "x09_cd45r0_cd45ra_te_cd8"      "x15_cd45ro_cd45ra_te_cd4"     
## [5] "x26_cd27_ig_d_naive_b_cells"   "x37_cd56_cd161_cd123_nk_cells"
5- CD4-CD8+ (CD8 T cells)
lineplots_cells[sig_cells_yellow$cell_type[1]]
## $x05_cd4_cd8_cd8_t_cells

8- CD45RO+CD45RA- (EM CD8)
lineplots_cells[sig_cells_yellow$cell_type[2]]
## $x08_cd45ro_cd45ra_em_cd8

9- CD45RO-CD45RA+ (TE CD4)
lineplots_cells[sig_cells_yellow$cell_type[3]]
## $x09_cd45r0_cd45ra_te_cd8

15- CD45RO-CD45RA+ (TE CD4)
lineplots_cells[sig_cells_yellow$cell_type[4]]
## $x15_cd45ro_cd45ra_te_cd4

26- CD27-IgD+ (Naive B cells)
lineplots_cells[sig_cells_yellow$cell_type[5]]
## $x26_cd27_ig_d_naive_b_cells

37- CD56+CD161+CD123- (NK cells)
lineplots_cells[sig_cells_yellow$cell_type[6]]
## $x37_cd56_cd161_cd123_nk_cells

fold change

Let’s look at the average fold change for significantly changing cells in yellow. We’ll look at the avg fold change comparing pre to post yellow, pre to post Red, and post-intervention comparison.

yellow_sigcells_subset <- cells_noOutlier_long %>%
  filter(cell_type %in% sig_cells_yellow$cell_type)%>%
  select(patient_id, pre_post_intervention, cell_type, cell_value) %>%
  group_by(cell_type) %>%
  pivot_wider(names_from = pre_post_intervention,
              values_from = cell_value) %>%
  mutate(yellow_FC = post_Yellow/pre_Yellow,
         red_FC = post_Red/pre_Red,
         post_intervention_FC = post_Red/post_Yellow)

yellow_sigcells_subset %>%
  summarize(mean_yellow_FC = mean(yellow_FC, na.rm = TRUE),
            mean_red_FC = mean(red_FC),
            mean_intervention_FC = mean(post_intervention_FC, na.rm = TRUE))
## # A tibble: 6 × 4
##   cell_type                     mean_yellow_FC mean_red_FC mean_intervention_FC
##   <chr>                                  <dbl>       <dbl>                <dbl>
## 1 x05_cd4_cd8_cd8_t_cells                 1.33        1.31                1.06 
## 2 x08_cd45ro_cd45ra_em_cd8                1.52        2.06                1.75 
## 3 x09_cd45r0_cd45ra_te_cd8                1.36        1.23                0.972
## 4 x15_cd45ro_cd45ra_te_cd4                1.60       48.0                20.5  
## 5 x26_cd27_ig_d_naive_b_cells             1.62        1.84                0.987
## 6 x37_cd56_cd161_cd123_nk_cells           1.52        1.20                3.62
# the fold change for cell type #15 was huge for red FC! subject 6108 had a very large increase post-red, so let's see what the fold change is like without that subject
yellow_sigcells_subset %>%
  filter(patient_id != 6108) %>%
  summarize(mean_yellow_FC = mean(yellow_FC, na.rm = TRUE),
            mean_red_FC = mean(red_FC),
            mean_intervention_FC = mean(post_intervention_FC, na.rm = TRUE))
## # A tibble: 6 × 4
##   cell_type                     mean_yellow_FC mean_red_FC mean_intervention_FC
##   <chr>                                  <dbl>       <dbl>                <dbl>
## 1 x05_cd4_cd8_cd8_t_cells                 1.32        1.10                0.933
## 2 x08_cd45ro_cd45ra_em_cd8                1.51        1.22                0.940
## 3 x09_cd45r0_cd45ra_te_cd8                1.35        1.28                1.01 
## 4 x15_cd45ro_cd45ra_te_cd4                1.54        1.42                0.930
## 5 x26_cd27_ig_d_naive_b_cells             1.59        1.77                0.935
## 6 x37_cd56_cd161_cd123_nk_cells           1.44        1.30                3.93

Red trt effects

Comparing pre- to post-yellow (low carotenoid) intervention

wilcox_cells_red <- cells_noOutlier_long %>%
  filter(intervention == "Red") %>%
  group_by(cell_type) %>%
  wilcox_test(cell_value ~ pre_post, paired = TRUE, p.adjust.method = "BH", detailed = TRUE)

kable(wilcox_cells_red, format = "markdown", digits = 3)
cell_type estimate .y. group1 group2 n1 n2 statistic p conf.low conf.high method alternative
x01_cd45_cd66b_lymph_dc_mono 0.676 cell_value pre post 12 12 63 0.064 -0.051 2.407 Wilcoxon two.sided
x02_cd45_cd66b_grans -0.250 cell_value pre post 12 12 22 0.204 -0.702 0.097 Wilcoxon two.sided
x03_cd3_cd45_cd3_t_cells 0.392 cell_value pre post 12 12 40 0.970 -12.266 14.584 Wilcoxon two.sided
x04_tc_rgd_cd3_ab_t_cells 0.624 cell_value pre post 12 12 41 0.910 -12.085 14.719 Wilcoxon two.sided
x05_cd4_cd8_cd8_t_cells -1.134 cell_value pre post 12 12 17 0.092 -3.764 0.352 Wilcoxon two.sided
x06_cd45ro_cd45ra_naive_cd8 -0.206 cell_value pre post 12 12 33 0.677 -1.184 0.832 Wilcoxon two.sided
x07_cd46ro_cd45ra_cm_cd8 -0.047 cell_value pre post 12 12 26 0.339 -0.176 0.054 Wilcoxon two.sided
x08_cd45ro_cd45ra_em_cd8 -0.904 cell_value pre post 12 12 13 0.043 -2.261 -0.013 Wilcoxon two.sided
x09_cd45r0_cd45ra_te_cd8 -0.130 cell_value pre post 12 12 31 0.569 -0.562 0.268 Wilcoxon two.sided
x10_cd38_hladr_activated_cd8 0.003 cell_value pre post 12 12 44 0.733 -0.032 0.039 Wilcoxon two.sided
x11_cd4_cd8_cd4_t_cells 2.054 cell_value pre post 12 12 44 0.733 -9.442 14.299 Wilcoxon two.sided
x12_cd45ro_cd45ra_naive_cd4 0.851 cell_value pre post 12 12 44 0.733 -2.927 8.874 Wilcoxon two.sided
x13_cd45ro_cd45ra_cm_cd4 0.850 cell_value pre post 12 12 49 0.470 -1.505 2.827 Wilcoxon two.sided
x14_cd45ro_cd45ra -0.421 cell_value pre post 12 12 19 0.129 -0.910 0.237 Wilcoxon two.sided
x15_cd45ro_cd45ra_te_cd4 -0.052 cell_value pre post 12 12 18 0.110 -0.178 0.008 Wilcoxon two.sided
x16_cd38_hladr_activated_cd4 0.028 cell_value pre post 12 12 52 0.339 -0.025 0.121 Wilcoxon two.sided
x17_cd25_cd127_tregs 0.025 cell_value pre post 12 12 50 0.424 -0.100 0.219 Wilcoxon two.sided
x18_ccr4_cd4_total_ccr4_treg 0.028 cell_value pre post 12 12 45 0.677 -0.077 0.215 Wilcoxon two.sided
x19_cd45ra_cd45ro_ccr4_treg_naive 0.002 cell_value pre post 12 12 45 0.677 -0.007 0.014 Wilcoxon two.sided
x20_hladr_total_ccr4_treg_activated 0.006 cell_value pre post 12 12 42 0.850 -0.054 0.066 Wilcoxon two.sided
x21_cd45ra_cd45ro_ccr4_treg_memory 0.037 cell_value pre post 12 12 48 0.519 -0.064 0.157 Wilcoxon two.sided
x22_cxcr3_ccr6_th1 -0.295 cell_value pre post 12 12 28 0.424 -0.995 0.206 Wilcoxon two.sided
x23_cxcr3_ccr6_th2 2.253 cell_value pre post 12 12 51 0.380 -3.040 15.172 Wilcoxon two.sided
x24_cxcr3_ccr6_th17 0.070 cell_value pre post 12 12 41 0.910 -0.905 1.131 Wilcoxon two.sided
x25_cd19_cd3_b_cells -3.122 cell_value pre post 12 12 5 0.005 -4.960 -0.788 Wilcoxon two.sided
x26_cd27_ig_d_naive_b_cells -2.445 cell_value pre post 12 12 9 0.016 -4.543 -0.476 Wilcoxon two.sided
x27_cd27_ig_d_memory_b_cells -0.174 cell_value pre post 12 12 24 0.266 -0.511 0.198 Wilcoxon two.sided
x28_cd27_ig_d_memory_resting_b_cells -0.061 cell_value pre post 12 12 16 0.077 -0.130 0.008 Wilcoxon two.sided
x30_cd27_cd38_plasmablasts 0.007 cell_value pre post 12 12 49 0.470 -0.016 0.048 Wilcoxon two.sided
x31_cd14_monocytes 1.280 cell_value pre post 12 12 43 0.791 -7.902 12.256 Wilcoxon two.sided
x32_cd16_non_classical_mono 0.578 cell_value pre post 12 12 49 0.470 -0.695 1.786 Wilcoxon two.sided
x33_cd16_classical_mono 0.725 cell_value pre post 12 12 39 1.000 -7.526 9.846 Wilcoxon two.sided
x34_hladr_cd56 1.101 cell_value pre post 12 12 43 0.791 -7.000 10.814 Wilcoxon two.sided
x35_cd16_cd123_cd11c_p_dc 0.076 cell_value pre post 12 12 51 0.380 -0.078 0.217 Wilcoxon two.sided
x36_cd16_cd123_cd11c_m_dc 0.267 cell_value pre post 12 12 39 1.000 -6.094 7.975 Wilcoxon two.sided
x37_cd56_cd161_cd123_nk_cells 0.186 cell_value pre post 12 12 43 0.791 -2.056 4.137 Wilcoxon two.sided
x38_cd16_nk_cells 0.217 cell_value pre post 12 12 49 0.470 -0.455 1.966 Wilcoxon two.sided
x40_cd14_mdsc_mono 0.805 cell_value pre post 12 12 48 0.519 -3.918 6.494 Wilcoxon two.sided
x41_cd66b_mdsc_grans 0.005 cell_value pre post 12 12 43 0.791 -0.232 0.086 Wilcoxon two.sided
# extract statistically significant cytokines 
(sig_cells_red <- wilcox_cells_red %>%
  filter(p < 0.05))
## # A tibble: 3 × 13
##   cell_type  estimate .y.   group1 group2    n1    n2 statistic       p conf.low
##   <chr>         <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>   <dbl>    <dbl>
## 1 x08_cd45r…   -0.904 cell… pre    post      12    12        13 0.0425     -2.26
## 2 x25_cd19_…   -3.12  cell… pre    post      12    12         5 0.00488    -4.96
## 3 x26_cd27_…   -2.45  cell… pre    post      12    12         9 0.0161     -4.54
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>

Sig cells

boxplots
cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_red$cell_type) %>%
  filter(intervention == "Red") %>%
  ggpaired(x = "pre_post", y = "cell_value", fill = "intervention", facet.by = "cell_type", short.panel.labs = FALSE, panel.labs = list(cell_type = c("CD45RO+ CD45RA- (EM CD8)","CD19+CD3- (B cells)", "CD27-IgD+ (Naive B cells)"))) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Tomato-soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell value",
       title = "Cell populations significantly different between pre- and post-Tomato soy",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

Let’s see what this looks like pre- and post- control

cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_red$cell_type) %>%
  filter(intervention == "Yellow") %>%
  ggpaired(x = "pre_post", y = "cell_value", fill = "intervention", facet.by = "cell_type", short.panel.labs = FALSE, panel.labs = list(cell_type = c("CD45RO+ CD45RA- (EM CD8)","CD19+CD3- (B cells)", "CD27-IgD+ (Naive B cells)"))) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Control"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.15) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell value",
       title = "Cell populations significantly different between pre- and post-Tomato soy",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

EM CD8 and Naive B- cells are significantly increased post control as well. Stronger effect in control.

lineplots

To get a sense of cell population percentages on the individual basis, we’ll look at line graphs.

8- CD45RO+CD45RA- (EM CD8)
lineplots_cells[sig_cells_red$cell_type[1]]
## $x08_cd45ro_cd45ra_em_cd8

25- CD19+CD3- (B cells)
lineplots_cells[sig_cells_red$cell_type[2]]
## $x25_cd19_cd3_b_cells

26- CD27-IgD+ (Naive B cells)
lineplots_cells[sig_cells_red$cell_type[3]]
## $x26_cd27_ig_d_naive_b_cells

fold change

Let’s look at the average fold change for significantly changing cells in red. We’ll look at the avg fold change comparing pre to post yellow, pre to post Red, and post-intervention comparison.

red_sigcells_subset <- cells_noOutlier_long %>%
  filter(cell_type %in% sig_cells_red$cell_type)%>%
  select(patient_id, pre_post_intervention, cell_type, cell_value) %>%
  group_by(cell_type) %>%
  pivot_wider(names_from = pre_post_intervention,
              values_from = cell_value) %>%
  mutate(yellow_FC = post_Yellow/pre_Yellow,
         red_FC = post_Red/pre_Red,
         post_intervention_FC = post_Red/post_Yellow)

red_sigcells_subset %>%
  summarize(mean_yellow_FC = mean(yellow_FC, na.rm = TRUE),
            mean_red_FC = mean(red_FC),
            mean_intervention_FC = mean(post_intervention_FC, na.rm = TRUE))
## # A tibble: 3 × 4
##   cell_type                   mean_yellow_FC mean_red_FC mean_intervention_FC
##   <chr>                                <dbl>       <dbl>                <dbl>
## 1 x08_cd45ro_cd45ra_em_cd8              1.52        2.06                1.75 
## 2 x25_cd19_cd3_b_cells                  1.49        1.64                0.972
## 3 x26_cd27_ig_d_naive_b_cells           1.62        1.84                0.987

Post-trt comparison

Comparing post-tomato soy to post-control intervention

wilcox_cells_intervention <- cells_noOutlier_long %>%
  filter(pre_post == "post",
         patient_id != "6112") %>%
  group_by(cell_type) %>%
  wilcox_test(cell_value ~ intervention, paired = TRUE, p.adjust.method = "BH", detailed = TRUE)

kable(wilcox_cells_intervention, format = "markdown", digits = 3)
cell_type estimate .y. group1 group2 n1 n2 statistic p conf.low conf.high method alternative
x01_cd45_cd66b_lymph_dc_mono 0.939 cell_value Yellow Red 11 11 40 0.577 -2.155 4.409 Wilcoxon two.sided
x02_cd45_cd66b_grans -0.332 cell_value Yellow Red 11 11 19 0.240 -1.196 0.487 Wilcoxon two.sided
x03_cd3_cd45_cd3_t_cells -6.112 cell_value Yellow Red 11 11 25 0.520 -16.628 9.710 Wilcoxon two.sided
x04_tc_rgd_cd3_ab_t_cells -5.992 cell_value Yellow Red 11 11 24 0.465 -16.693 9.095 Wilcoxon two.sided
x05_cd4_cd8_cd8_t_cells -1.102 cell_value Yellow Red 11 11 29 0.765 -4.900 4.591 Wilcoxon two.sided
x06_cd45ro_cd45ra_naive_cd8 -0.099 cell_value Yellow Red 11 11 33 1.000 -3.458 3.790 Wilcoxon two.sided
x07_cd46ro_cd45ra_cm_cd8 -0.023 cell_value Yellow Red 11 11 30 0.831 -0.273 0.239 Wilcoxon two.sided
x08_cd45ro_cd45ra_em_cd8 0.085 cell_value Yellow Red 11 11 34 0.966 -4.807 3.087 Wilcoxon two.sided
x09_cd45r0_cd45ra_te_cd8 0.353 cell_value Yellow Red 11 11 41 0.520 -0.679 1.444 Wilcoxon two.sided
x10_cd38_hladr_activated_cd8 0.023 cell_value Yellow Red 11 11 50 0.147 -0.013 0.060 Wilcoxon two.sided
x11_cd4_cd8_cd4_t_cells -3.659 cell_value Yellow Red 11 11 24 0.465 -14.703 6.861 Wilcoxon two.sided
x12_cd45ro_cd45ra_naive_cd4 -1.463 cell_value Yellow Red 11 11 27 0.638 -9.292 4.505 Wilcoxon two.sided
x13_cd45ro_cd45ra_cm_cd4 -0.406 cell_value Yellow Red 11 11 30 0.831 -5.530 5.506 Wilcoxon two.sided
x14_cd45ro_cd45ra 0.190 cell_value Yellow Red 11 11 35 0.898 -1.565 1.691 Wilcoxon two.sided
x15_cd45ro_cd45ra_te_cd4 -0.006 cell_value Yellow Red 11 11 31 0.898 -6.261 0.342 Wilcoxon two.sided
x16_cd38_hladr_activated_cd4 0.045 cell_value Yellow Red 11 11 43 0.413 -0.118 0.217 Wilcoxon two.sided
x17_cd25_cd127_tregs -0.030 cell_value Yellow Red 11 11 31 0.898 -0.225 0.779 Wilcoxon two.sided
x18_ccr4_cd4_total_ccr4_treg -0.010 cell_value Yellow Red 11 11 32 0.966 -0.227 0.774 Wilcoxon two.sided
x19_cd45ra_cd45ro_ccr4_treg_naive 0.004 cell_value Yellow Red 11 11 39 0.638 -0.014 0.032 Wilcoxon two.sided
x20_hladr_total_ccr4_treg_activated 0.071 cell_value Yellow Red 11 11 46 0.278 -0.060 0.212 Wilcoxon two.sided
x21_cd45ra_cd45ro_ccr4_treg_memory -0.012 cell_value Yellow Red 11 11 31 0.898 -0.213 0.501 Wilcoxon two.sided
x22_cxcr3_ccr6_th1 -0.319 cell_value Yellow Red 11 11 29 0.765 -1.790 1.121 Wilcoxon two.sided
x23_cxcr3_ccr6_th2 -2.599 cell_value Yellow Red 11 11 27 0.638 -10.608 7.891 Wilcoxon two.sided
x24_cxcr3_ccr6_th17 0.108 cell_value Yellow Red 11 11 34 0.966 -3.746 4.798 Wilcoxon two.sided
x25_cd19_cd3_b_cells -0.635 cell_value Yellow Red 11 11 28 0.700 -5.464 6.970 Wilcoxon two.sided
x26_cd27_ig_d_naive_b_cells -0.199 cell_value Yellow Red 11 11 32 0.966 -5.914 5.040 Wilcoxon two.sided
x27_cd27_ig_d_memory_b_cells 0.191 cell_value Yellow Red 11 11 41 0.520 -0.497 0.844 Wilcoxon two.sided
x28_cd27_ig_d_memory_resting_b_cells 0.043 cell_value Yellow Red 11 11 34 0.966 -0.341 0.346 Wilcoxon two.sided
x30_cd27_cd38_plasmablasts 0.018 cell_value Yellow Red 11 11 43 0.413 -0.020 0.067 Wilcoxon two.sided
x31_cd14_monocytes 5.496 cell_value Yellow Red 11 11 42 0.465 -7.390 12.925 Wilcoxon two.sided
x32_cd16_non_classical_mono -0.170 cell_value Yellow Red 11 11 26 0.577 -0.805 0.372 Wilcoxon two.sided
x33_cd16_classical_mono 4.795 cell_value Yellow Red 11 11 43 0.413 -7.726 13.178 Wilcoxon two.sided
x34_hladr_cd56 4.297 cell_value Yellow Red 11 11 41 0.520 -6.792 11.745 Wilcoxon two.sided
x35_cd16_cd123_cd11c_p_dc 0.070 cell_value Yellow Red 11 11 46 0.278 -0.067 0.157 Wilcoxon two.sided
x36_cd16_cd123_cd11c_m_dc 3.045 cell_value Yellow Red 11 11 42 0.465 -6.255 12.109 Wilcoxon two.sided
x37_cd56_cd161_cd123_nk_cells -4.028 cell_value Yellow Red 11 11 14 0.102 -9.791 0.180 Wilcoxon two.sided
x38_cd16_nk_cells 2.788 cell_value Yellow Red 11 11 63 0.005 1.068 5.805 Wilcoxon two.sided
x40_cd14_mdsc_mono -7.563 cell_value Yellow Red 11 11 0 0.001 -20.535 -2.532 Wilcoxon two.sided
x41_cd66b_mdsc_grans -0.011 cell_value Yellow Red 11 11 29 0.765 -0.345 0.219 Wilcoxon two.sided
# extract statistically significant cytokines 
(sig_cells_intervention <- wilcox_cells_intervention %>%
  filter(p < 0.05))
## # A tibble: 2 × 13
##   cell_type  estimate .y.   group1 group2    n1    n2 statistic       p conf.low
##   <chr>         <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>   <dbl>    <dbl>
## 1 x38_cd16_…     2.79 cell… Yellow Red       11    11        63 4.88e-3     1.07
## 2 x40_cd14_…    -7.56 cell… Yellow Red       11    11         0 9.77e-4   -20.5 
## # ℹ 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>

Sig cells

boxplots
cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_intervention$cell_type) %>%
  filter(pre_post == "post") %>%
  ggpaired(x = "pre_post_intervention", y = "cell_value", fill = "intervention", facet.by = "cell_type") +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Control", "Tomato-soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.25) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell value",
       title = "Cell populations significantly different between post-Control and post-Tomato soy juices",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH", comparisons = list(c("post_Yellow", "post_Red")), label.y = 40)

Let’s look at the trends for these cell types during individual interventions

cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_intervention$cell_type) %>%
  filter(intervention == "Red") %>%
  ggpaired(x = "pre_post", y = "cell_value", fill = "intervention", facet.by = "cell_type", short.panel.labs = FALSE, panel.labs = list(cell_type = c("CD16- NK cells","CD14+ MDSC (Mono)"))) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Tomato-soy"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.25) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell value",
       title = "Cell populations significantly different between post-Control and post-Tomato soy juices",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

cells_noOutlier_long %>% 
  filter(cell_type %in% sig_cells_intervention$cell_type) %>%
  filter(intervention == "Yellow") %>%
  ggpaired(x = "pre_post", y = "cell_value", fill = "intervention", facet.by = "cell_type", short.panel.labs = FALSE, panel.labs = list(cell_type = c("CD16- NK cells","CD14+ MDSC (Mono)"))) +
  scale_fill_manual(values = c("Yellow" = "yellow1",
                               "Red" = "tomato1"),
                    labels = c("Control"),
                    name = "Intervention") +
  geom_line(aes(group = patient_id), colour = "gray", size = 0.25) +
  theme_clean(base_size = 18, base_family = "sans") +
  labs(x = "",
       y = "Cell value",
       title = "Cell populations significantly different between post-Control and post-Tomato soy juices",
       subtitle = "") +
  stat_compare_means(method = "wilcox.test", paired = TRUE, p.adjust.method = "BH")

lineplots

To get a sense of cell population percentages on the individual basis, we’ll look at line graphs.

38- CD16- NK cells
lineplots_cells[sig_cells_intervention$cell_type[1]]
## $x38_cd16_nk_cells

Looking at post control v post tomato soy

imputed_meta_table %>% 
  filter(pre_post == "post") %>%
  ggplot(aes(x = pre_post_intervention, y = x38_cd16_nk_cells, color = patient_id)) +
  geom_line(aes(group = patient_id)) +
  theme_bw() +
  labs(x = "Timepoint",
       y = "Population level (%)",
       title = "CD16- NK Cell populations in each patient between post- interventions")

40- CD14+ MDSC (Mono)
lineplots_cells[sig_cells_intervention$cell_type[2]]
## $x40_cd14_mdsc_mono

Let’s look at post control vs post tomato soy

imputed_meta_table %>% 
  filter(pre_post == "post") %>%
  ggplot(aes(x = pre_post_intervention, y = x40_cd14_mdsc_mono, color = patient_id)) +
  geom_line(aes(group = patient_id)) +
  theme_bw() +
  labs(x = "Timepoint",
       y = "Population level (%)",
       title = "CD14+ monocytic MDSC populations in each patient between post- interventions")

fold change

Let’s look at the average fold change for significantly changing cells in red. We’ll look at the avg fold change comparing pre to post yellow, pre to post Red, and post-intervention comparison.

intervention_sigcells_subset <- cells_noOutlier_long %>%
  filter(cell_type %in% sig_cells_intervention$cell_type)%>%
  select(patient_id, pre_post_intervention, cell_type, cell_value) %>%
  group_by(cell_type) %>%
  pivot_wider(names_from = pre_post_intervention,
              values_from = cell_value) %>%
  mutate(yellow_FC = post_Yellow/pre_Yellow,
         red_FC = post_Red/pre_Red,
         post_intervention_FC = post_Red/post_Yellow)

intervention_sigcells_subset %>%
  summarize(mean_yellow_FC = mean(yellow_FC, na.rm = TRUE),
            mean_red_FC = mean(red_FC),
            mean_intervention_FC = mean(post_intervention_FC, na.rm = TRUE))
## # A tibble: 2 × 4
##   cell_type          mean_yellow_FC mean_red_FC mean_intervention_FC
##   <chr>                       <dbl>       <dbl>                <dbl>
## 1 x38_cd16_nk_cells           1.25         1.08                0.427
## 2 x40_cd14_mdsc_mono          0.976        1.52               43.7

Very large fold change of approx 44 units higher post-Red vs. post-Yellow for MDSC cell type.

Correlation analyses

Let’s look at the correlation between significant immuno outcomes (from each comparison) and carotenoids. I also plan to correlate these with urinary soy isoflavones and their metabolites, along with other significant urinary metabolites. I will perform a log2 fold change transformation for pre-post comparison and intervention comparisons.

Yellow

Pre vs post yellow

wrangling

# create df with pre-interventions data
meta_table_pre_subset <- imputed_meta_table %>%
  filter(pre_post == "pre") %>%
  mutate_at(11:ncol(.), log2)

# create df with post-interventions data
meta_table_post_subset <- imputed_meta_table %>%
  filter(pre_post == "post") %>%
  mutate_at(11:ncol(.), log2)

# subtract pre df from post df
meta_table_post_pre_differences <- meta_table_post_subset[,11:ncol(imputed_meta_table)] - meta_table_pre_subset[,11:ncol(imputed_meta_table)]

# add metadata back in and organize so that metadata is at beginning of df
meta_table_post_pre_differences <- meta_table_post_pre_differences %>%
  mutate(patient_id = meta_table_post_subset$patient_id,
         intervention = meta_table_post_subset$intervention,
         age_at_enrollment = meta_table_post_subset$age_at_enrollment,
         sex = meta_table_post_subset$sex,
         bmi_at_enrollment = meta_table_post_subset$bmi_at_enrollment) %>%
  relocate(patient_id, intervention, sex, age_at_enrollment, bmi_at_enrollment)

Corr table

correlation_yellow <- meta_table_post_pre_differences %>%
  filter(intervention == "Yellow") %>%
  filter(patient_id != 6112) %>% # remove this subj since they were an outlier in control juice for total lyc
  select(total_lyc, all_of(sig_cells_yellow$cell_type), all_of(sig_cytokines_yellow$cytokine)) %>%
  correlate(method = "spearman")

kable(correlation_yellow, format = "markdown", digits = 3)
term total_lyc x05_cd4_cd8_cd8_t_cells x08_cd45ro_cd45ra_em_cd8 x09_cd45r0_cd45ra_te_cd8 x15_cd45ro_cd45ra_te_cd4 x26_cd27_ig_d_naive_b_cells x37_cd56_cd161_cd123_nk_cells
total_lyc NA -0.627 -0.545 -0.573 -0.291 -0.473 0.000
x05_cd4_cd8_cd8_t_cells -0.627 NA 0.273 0.609 0.455 0.673 -0.500
x08_cd45ro_cd45ra_em_cd8 -0.545 0.273 NA 0.518 0.418 0.100 0.209
x09_cd45r0_cd45ra_te_cd8 -0.573 0.609 0.518 NA 0.800 0.555 -0.264
x15_cd45ro_cd45ra_te_cd4 -0.291 0.455 0.418 0.800 NA 0.491 -0.009
x26_cd27_ig_d_naive_b_cells -0.473 0.673 0.100 0.555 0.491 NA -0.436
x37_cd56_cd161_cd123_nk_cells 0.000 -0.500 0.209 -0.264 -0.009 -0.436 NA
correlation_yellow %>%
  rearrange(absolute = FALSE) %>%
  shave() %>%
  rplot(shape = 19,
        colors = c("red", "green"),
        print_cor = TRUE) +
  theme(axis.text.x = element_text(angle = 90))

Red

correlation_red <- meta_table_post_pre_differences %>%
  filter(intervention == "Red") %>%
  select(total_lyc, all_of(sig_cells_red$cell_type), all_of(sig_cytokines_red$cytokine)) %>%
  correlate(method = "spearman")

kable(correlation_red, format = "markdown", digits = 3)
term total_lyc x08_cd45ro_cd45ra_em_cd8 x25_cd19_cd3_b_cells x26_cd27_ig_d_naive_b_cells gm_csf il_12p70 il_5
total_lyc NA 0.091 0.140 0.035 0.007 -0.270 -0.189
x08_cd45ro_cd45ra_em_cd8 0.091 NA 0.168 0.238 0.427 0.147 0.070
x25_cd19_cd3_b_cells 0.140 0.168 NA 0.958 0.042 -0.021 -0.161
x26_cd27_ig_d_naive_b_cells 0.035 0.238 0.958 NA 0.007 -0.102 -0.224
gm_csf 0.007 0.427 0.042 0.007 NA 0.361 -0.028
il_12p70 -0.270 0.147 -0.021 -0.102 0.361 NA 0.666
il_5 -0.189 0.070 -0.161 -0.224 -0.028 0.666 NA
correlation_red %>%
  rearrange(absolute = FALSE) %>%
  shave() %>%
  rplot(shape = 19,
        colors = c("red", "green"),
        print_cor = TRUE) +
  theme(axis.text.x = element_text(angle = 90))

Intervention comparison

wrangling

# create df with pre-interventions data
meta_table_postY_subset <- imputed_meta_table %>%
  filter(pre_post_intervention == "post_Yellow") %>%
  mutate_at(11:ncol(.), log2)

# create df with post-interventions data
meta_table_postR_subset <- imputed_meta_table %>%
  filter(pre_post_intervention == "post_Red") %>%
  mutate_at(11:ncol(.), log2)

# subtract pre df from post df
meta_table_intervention_differences <- meta_table_postR_subset[,11:ncol(imputed_meta_table)] - meta_table_postY_subset[,11:ncol(imputed_meta_table)]

# add metadata back in and organize so that metadata is at beginning of df
meta_table_intervention_differences <- meta_table_intervention_differences %>%
  mutate(patient_id = meta_table_postR_subset$patient_id,
         intervention = meta_table_postR_subset$intervention,
         age_at_enrollment = meta_table_postR_subset$age_at_enrollment,
         sex = meta_table_postR_subset$sex,
         bmi_at_enrollment = meta_table_postR_subset$bmi_at_enrollment) %>%
  relocate(patient_id, intervention, sex, age_at_enrollment, bmi_at_enrollment)
correlation_intervention <- meta_table_intervention_differences %>%
  filter(intervention == "Red") %>%
  select(total_lyc, all_of(sig_cells_intervention$cell_type), all_of(sig_cytokines_intervention$cytokine)) %>%
  correlate(method = "spearman")

kable(correlation_intervention, format = "markdown", digits = 3)
term total_lyc x38_cd16_nk_cells x40_cd14_mdsc_mono
total_lyc NA -0.175 -0.140
x38_cd16_nk_cells -0.175 NA 0.126
x40_cd14_mdsc_mono -0.140 0.126 NA
correlation_intervention %>%
  rearrange(absolute = FALSE) %>%
  shave() %>%
  rplot(shape = 19,
        colors = c("red", "green"),
        print_cor = TRUE)

Overall corr

Let’s take all of the significant outcomes and even add all of the metadata

pre v post difference

correlation_all_pre_post_sig <- meta_table_post_pre_differences %>%
  select(2:5, total_lyc, total_carotenoids, a_carotene, b_carotene, lutein, zeaxanthin, b_cryptoxanthin, all_of(sig_cells_red$cell_type), all_of(sig_cytokines_red$cytokine), all_of(sig_cells_yellow$cell_type), all_of(sig_cytokines_yellow$cytokine), all_of(sig_cells_intervention$cell_type), all_of(sig_cytokines_intervention$cytokine)) %>%
  correlate(method = "spearman")

kable(correlation_all_pre_post_sig, format = "markdown", digits = 3)
term age_at_enrollment bmi_at_enrollment total_lyc total_carotenoids a_carotene b_carotene lutein zeaxanthin b_cryptoxanthin x08_cd45ro_cd45ra_em_cd8 x25_cd19_cd3_b_cells x26_cd27_ig_d_naive_b_cells gm_csf il_12p70 il_5 x05_cd4_cd8_cd8_t_cells x09_cd45r0_cd45ra_te_cd8 x15_cd45ro_cd45ra_te_cd4 x37_cd56_cd161_cd123_nk_cells x38_cd16_nk_cells x40_cd14_mdsc_mono
age_at_enrollment NA 0.490 -0.134 -0.101 -0.234 -0.143 -0.178 0.040 0.110 0.256 0.026 0.087 -0.223 -0.112 0.033 0.387 0.038 0.192 0.106 0.007 -0.169
bmi_at_enrollment 0.490 NA -0.146 -0.047 0.143 -0.096 0.023 0.077 -0.061 0.094 -0.070 0.000 -0.230 0.007 -0.131 0.366 0.267 0.077 0.201 -0.242 0.218
total_lyc -0.134 -0.146 NA 0.819 0.120 0.676 0.161 -0.365 0.082 -0.363 0.023 0.036 -0.157 -0.490 -0.424 -0.348 -0.262 -0.163 -0.267 0.083 0.029
total_carotenoids -0.101 -0.047 0.819 NA 0.378 0.847 0.527 -0.175 0.211 -0.226 -0.143 -0.117 -0.217 -0.347 -0.365 -0.350 -0.201 -0.210 -0.035 0.051 0.141
a_carotene -0.234 0.143 0.120 0.378 NA 0.530 0.437 0.194 0.117 0.409 -0.195 -0.232 0.218 0.217 0.220 0.054 0.354 0.244 0.290 0.073 0.369
b_carotene -0.143 -0.096 0.676 0.847 0.530 NA 0.396 -0.300 -0.092 -0.063 -0.340 -0.347 -0.036 -0.131 -0.124 -0.303 -0.092 -0.088 0.123 0.183 0.326
lutein -0.178 0.023 0.161 0.527 0.437 0.396 NA 0.288 0.150 0.245 -0.092 -0.011 0.063 0.004 -0.205 0.058 -0.042 0.014 0.089 -0.106 0.004
zeaxanthin 0.040 0.077 -0.365 -0.175 0.194 -0.300 0.288 NA 0.170 0.253 0.117 0.165 -0.157 0.400 0.268 0.202 -0.109 0.003 0.096 -0.075 -0.219
b_cryptoxanthin 0.110 -0.061 0.082 0.211 0.117 -0.092 0.150 0.170 NA 0.124 0.148 0.182 -0.121 -0.077 -0.124 -0.028 0.102 -0.003 0.153 0.038 0.068
x08_cd45ro_cd45ra_em_cd8 0.256 0.094 -0.363 -0.226 0.409 -0.063 0.245 0.253 0.124 NA 0.101 0.088 0.312 0.350 0.411 0.523 0.441 0.677 0.378 0.083 0.167
x25_cd19_cd3_b_cells 0.026 -0.070 0.023 -0.143 -0.195 -0.340 -0.092 0.117 0.148 0.101 NA 0.963 -0.070 -0.044 0.063 0.462 0.382 0.530 -0.323 -0.183 -0.213
x26_cd27_ig_d_naive_b_cells 0.087 0.000 0.036 -0.117 -0.232 -0.347 -0.011 0.165 0.182 0.088 0.963 NA -0.047 -0.073 -0.073 0.581 0.308 0.512 -0.406 -0.288 -0.324
gm_csf -0.223 -0.230 -0.157 -0.217 0.218 -0.036 0.063 -0.157 -0.121 0.312 -0.070 -0.047 NA 0.267 0.136 0.215 -0.002 0.244 0.023 -0.046 -0.098
il_12p70 -0.112 0.007 -0.490 -0.347 0.217 -0.131 0.004 0.400 -0.077 0.350 -0.044 -0.073 0.267 NA 0.556 0.114 0.204 0.125 0.584 0.341 0.142
il_5 0.033 -0.131 -0.424 -0.365 0.220 -0.124 -0.205 0.268 -0.124 0.411 0.063 -0.073 0.136 0.556 NA 0.028 0.320 0.273 0.402 0.568 0.186
x05_cd4_cd8_cd8_t_cells 0.387 0.366 -0.348 -0.350 0.054 -0.303 0.058 0.202 -0.028 0.523 0.462 0.581 0.215 0.114 0.028 NA 0.461 0.678 -0.158 -0.428 -0.154
x09_cd45r0_cd45ra_te_cd8 0.038 0.267 -0.262 -0.201 0.354 -0.092 -0.042 -0.109 0.102 0.441 0.382 0.308 -0.002 0.204 0.320 0.461 NA 0.566 0.234 0.015 0.258
x15_cd45ro_cd45ra_te_cd4 0.192 0.077 -0.163 -0.210 0.244 -0.088 0.014 0.003 -0.003 0.677 0.530 0.512 0.244 0.125 0.273 0.678 0.566 NA 0.110 0.041 -0.012
x37_cd56_cd161_cd123_nk_cells 0.106 0.201 -0.267 -0.035 0.290 0.123 0.089 0.096 0.153 0.378 -0.323 -0.406 0.023 0.584 0.402 -0.158 0.234 0.110 NA 0.589 0.464
x38_cd16_nk_cells 0.007 -0.242 0.083 0.051 0.073 0.183 -0.106 -0.075 0.038 0.083 -0.183 -0.288 -0.046 0.341 0.568 -0.428 0.015 0.041 0.589 NA 0.103
x40_cd14_mdsc_mono -0.169 0.218 0.029 0.141 0.369 0.326 0.004 -0.219 0.068 0.167 -0.213 -0.324 -0.098 0.142 0.186 -0.154 0.258 -0.012 0.464 0.103 NA
correlation_all_pre_post_sig %>%
  rearrange(absolute = FALSE) %>%
  shave() %>%
  rplot(shape = 19, 
        print_cor = TRUE,
        colors = c("red", "green")) +
  theme(axis.text.x = element_text(angle = 90))

post red vs post yellow difference

correlation_all_intervention_sig <- meta_table_intervention_differences %>%
  select(2:5, total_lyc, total_carotenoids, a_carotene, b_carotene, lutein, zeaxanthin, b_cryptoxanthin, all_of(sig_cells_red$cell_type), all_of(sig_cytokines_red$cytokine), all_of(sig_cells_yellow$cell_type), all_of(sig_cytokines_yellow$cytokine), all_of(sig_cells_intervention$cell_type), all_of(sig_cytokines_intervention$cytokine)) %>%
  correlate(method = "spearman")

kable(correlation_all_intervention_sig, format = "markdown", digits = 3)
term age_at_enrollment bmi_at_enrollment total_lyc total_carotenoids a_carotene b_carotene lutein zeaxanthin b_cryptoxanthin x08_cd45ro_cd45ra_em_cd8 x25_cd19_cd3_b_cells x26_cd27_ig_d_naive_b_cells gm_csf il_12p70 il_5 x05_cd4_cd8_cd8_t_cells x09_cd45r0_cd45ra_te_cd8 x15_cd45ro_cd45ra_te_cd4 x37_cd56_cd161_cd123_nk_cells x38_cd16_nk_cells x40_cd14_mdsc_mono
age_at_enrollment NA 0.490 0.056 -0.007 -0.238 0.343 0.014 0.455 -0.203 0.105 0.538 0.510 0.322 0.385 0.224 0.035 0.266 0.294 -0.147 -0.105 -0.147
bmi_at_enrollment 0.490 NA -0.126 -0.098 -0.049 0.189 -0.231 0.119 -0.119 -0.406 0.063 0.021 0.287 0.252 0.028 -0.490 0.161 -0.357 0.615 0.147 0.350
total_lyc 0.056 -0.126 NA 0.797 0.545 0.434 0.741 0.643 0.587 -0.294 -0.280 -0.196 0.301 0.091 0.329 -0.294 -0.273 0.280 -0.119 -0.175 -0.140
total_carotenoids -0.007 -0.098 0.797 NA 0.601 0.671 0.944 0.587 0.867 -0.385 -0.161 -0.203 0.182 0.070 0.413 -0.510 -0.343 -0.028 0.056 -0.294 -0.063
a_carotene -0.238 -0.049 0.545 0.601 NA 0.490 0.434 0.098 0.727 -0.441 -0.427 -0.399 -0.161 -0.175 0.133 -0.294 -0.888 -0.294 0.182 0.049 -0.098
b_carotene 0.343 0.189 0.434 0.671 0.490 NA 0.608 0.245 0.497 -0.056 -0.105 -0.196 -0.126 -0.056 0.552 -0.322 -0.350 -0.021 -0.028 -0.469 -0.287
lutein 0.014 -0.231 0.741 0.944 0.434 0.608 NA 0.650 0.804 -0.224 -0.049 -0.042 0.287 0.126 0.476 -0.413 -0.196 0.168 -0.049 -0.385 -0.273
zeaxanthin 0.455 0.119 0.643 0.587 0.098 0.245 0.650 NA 0.399 -0.231 0.231 0.266 0.629 0.538 0.329 -0.224 0.140 0.371 -0.028 -0.210 -0.035
b_cryptoxanthin -0.203 -0.119 0.587 0.867 0.727 0.497 0.804 0.399 NA -0.587 -0.175 -0.168 0.070 -0.028 0.091 -0.559 -0.615 -0.343 0.182 -0.091 -0.035
x08_cd45ro_cd45ra_em_cd8 0.105 -0.406 -0.294 -0.385 -0.441 -0.056 -0.224 -0.231 -0.587 NA -0.091 -0.105 -0.392 -0.385 0.119 0.839 0.413 0.685 -0.636 -0.573 -0.301
x25_cd19_cd3_b_cells 0.538 0.063 -0.280 -0.161 -0.427 -0.105 -0.049 0.231 -0.175 -0.091 NA 0.944 0.503 0.748 0.175 -0.091 0.273 0.028 0.049 0.392 -0.252
x26_cd27_ig_d_naive_b_cells 0.510 0.021 -0.196 -0.203 -0.399 -0.196 -0.042 0.266 -0.168 -0.105 0.944 NA 0.615 0.727 0.126 -0.077 0.238 0.140 0.014 0.441 -0.420
gm_csf 0.322 0.287 0.301 0.182 -0.161 -0.126 0.287 0.629 0.070 -0.392 0.503 0.615 NA 0.797 0.420 -0.490 0.357 0.245 0.350 0.392 -0.189
il_12p70 0.385 0.252 0.091 0.070 -0.175 -0.056 0.126 0.538 -0.028 -0.385 0.748 0.727 0.797 NA 0.420 -0.371 0.217 0.049 0.343 0.448 -0.133
il_5 0.224 0.028 0.329 0.413 0.133 0.552 0.476 0.329 0.091 0.119 0.175 0.126 0.420 0.420 NA -0.259 0.140 0.434 0.000 -0.112 -0.413
x05_cd4_cd8_cd8_t_cells 0.035 -0.490 -0.294 -0.510 -0.294 -0.322 -0.413 -0.224 -0.559 0.839 -0.091 -0.077 -0.490 -0.371 -0.259 NA 0.147 0.531 -0.657 -0.357 -0.147
x09_cd45r0_cd45ra_te_cd8 0.266 0.161 -0.273 -0.343 -0.888 -0.350 -0.196 0.140 -0.615 0.413 0.273 0.238 0.357 0.217 0.140 0.147 NA 0.455 -0.084 -0.161 0.168
x15_cd45ro_cd45ra_te_cd4 0.294 -0.357 0.280 -0.028 -0.294 -0.021 0.168 0.371 -0.343 0.685 0.028 0.140 0.245 0.049 0.434 0.531 0.455 NA -0.643 -0.371 -0.434
x37_cd56_cd161_cd123_nk_cells -0.147 0.615 -0.119 0.056 0.182 -0.028 -0.049 -0.028 0.182 -0.636 0.049 0.014 0.350 0.343 0.000 -0.657 -0.084 -0.643 NA 0.350 0.217
x38_cd16_nk_cells -0.105 0.147 -0.175 -0.294 0.049 -0.469 -0.385 -0.210 -0.091 -0.573 0.392 0.441 0.392 0.448 -0.112 -0.357 -0.161 -0.371 0.350 NA 0.126
x40_cd14_mdsc_mono -0.147 0.350 -0.140 -0.063 -0.098 -0.287 -0.273 -0.035 -0.035 -0.301 -0.252 -0.420 -0.189 -0.133 -0.413 -0.147 0.168 -0.434 0.217 0.126 NA
correlation_all_intervention_sig %>%
  rearrange(absolute = FALSE) %>%
  shave() %>%
  rplot(shape = 19, 
        print_cor = TRUE,
        colors = c("red", "green")) +
  theme(axis.text.x = element_text(angle = 90))

Heatmap

Significant cytokines

Z-score transformed

Here, I am using my raw data and allowing the pheatmap package to perform z-scaling.

Z-scoring standardizes the data by this calculation: (individual value within outcome - mean of outcome) / (std dev). The pheatmap package does this automatically with the call scale = “row” or “column”

cytokine_heatmap_data <- imputed_meta_table %>%
  unite("subject_pre_post_intervention", patient_id, pre_post_intervention, sep = "_", remove = FALSE) %>%
  dplyr::select(patient_id, subject_pre_post_intervention, pre_post, all_of(sig_cytokines_red$cytokine), all_of(sig_cytokines_yellow$cytokine), all_of(sig_cytokines_intervention$cytokine))


cytokine_heatmap <- 
  pheatmap(cytokine_heatmap_data[,-c(1:3)],
           scale = "column", # z-scaling
           cluster_rows = TRUE,
           cutree_rows = 6,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D2",
           labels_row = cytokine_heatmap_data$subject_pre_post_intervention,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of significant immuno outcomes across timepoints \nby paired T-tests \nBenjamoni-Hochberg corrected p-values > 0.05 \nC18 (-)")

All cytokines

Z-score transformed

cytokines_all_heatmap_data <- imputed_meta_table %>%
  unite("subject_pre_post_intervention", patient_id, pre_post_intervention, sep = "_", remove = FALSE) %>%
  dplyr::select(patient_id, subject_pre_post_intervention, pre_post, all_of(cytokines_long$cytokine))


cytokines_all_heatmap <- 
  pheatmap(cytokines_all_heatmap_data[,-c(1:3)],
           scale = "column", # z-scaling
           cluster_rows = TRUE,
           cutree_rows = 4,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D",
           labels_row = cytokines_all_heatmap_data$subject_pre_post_intervention,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of all cytokines from multiplex assay")

Normalized to controls

I want to try a different technique here to see if we can capture variation by bringing the values to a visually meaningful range by normalizing values against “controls”. Each subject serves as their own control pre-intervention (and also when they are on the low carotenoid/soy intervention (Yellow)). These dfs will be different from the log2 fold change dfs calculated for correlation plots. In this case, we will take every treatment and divide it by its control (so control should be end up being 0)

# make a string of metadata and of immuno outcomes for ease
str_meta <- colnames(imputed_meta_table[,1:10])
str_immuno <- colnames(imputed_meta_table[,11:82])

# Extract pre-intervention data and set immuno outcome columns to 0
pre_data_zeros <- imputed_meta_table %>%
  filter(pre_post == "pre") %>%
  mutate(across(all_of(str_immuno), ~ 0))

# Combine pre-intervention zeros with log fold change table
normalized_to_pre <- meta_table_post_pre_differences %>%
  mutate(pre_post = "normalized_POST") %>%
  bind_rows(pre_data_zeros %>%
              select(str_meta[c(1:4, 6)], all_of(str_immuno)) %>%
              mutate(pre_post = "normalized_PRE")) %>%
  unite("pre_post_intervention", pre_post, intervention, sep = "_", remove = FALSE)
cytokines_normlog2FC_heatmap_data <- normalized_to_pre %>%
  unite("subj_pre_post_intervention", patient_id, pre_post_intervention, sep = "_", remove = FALSE) %>% 
  filter(pre_post == "normalized_POST") %>%
  dplyr::select(subj_pre_post_intervention, all_of(cytokines_long$cytokine))


cytokines_normtopre_heatmap <- 
  pheatmap(cytokines_normlog2FC_heatmap_data[,-1],
           cluster_rows = TRUE,
           cutree_rows = 2,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D",
           labels_row = cytokines_normlog2FC_heatmap_data$subj_pre_post_intervention,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of all cytokines from multiplex assay")

cytokines2_normlog2FC_heatmap_data <- normalized_to_pre %>%
  unite("subj_pre_post_intervention", patient_id, pre_post_intervention, sep = "_", remove = FALSE) %>% 
  dplyr::select(subj_pre_post_intervention, all_of(cytokines_long$cytokine))


cytokines2_normtopre_heatmap <- 
  pheatmap(cytokines2_normlog2FC_heatmap_data[,-1],
           cluster_rows = TRUE,
           cutree_rows = 2,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D",
           labels_row = cytokines2_normlog2FC_heatmap_data$subj_pre_post_intervention,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of all cytokines from multiplex assay")

Yellow

yellow_norm_to_pre <- normalized_to_pre %>%
  filter(intervention == "Yellow")
cytokines_normlog2FC_yellow_heatmap_data <- yellow_norm_to_pre %>%
  unite("subject_pre_post", patient_id, pre_post, sep = "_", remove = FALSE) %>%
  dplyr::select(subject_pre_post, all_of(cytokines_long$cytokine))


cytokines_yellow_heatmap <- 
  pheatmap(cytokines_normlog2FC_yellow_heatmap_data[,-1],
           cluster_rows = TRUE,
           cutree_rows = 2,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D",
           labels_row = cytokines_normlog2FC_yellow_heatmap_data$subject_pre_post,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of all cytokines from multiplex assay")

Red

red_norm_to_pre <- normalized_to_pre %>%
  filter(intervention == "Red")
cytokines_normlog2FC_red_heatmap_data <- red_norm_to_pre %>%
  unite("subject_pre_post", patient_id, pre_post, sep = "_", remove = FALSE) %>%
  dplyr::select(subject_pre_post, all_of(cytokines_long$cytokine))


cytokines_red_heatmap <- 
  pheatmap(cytokines_normlog2FC_red_heatmap_data[,-1],
           cluster_rows = TRUE,
           cutree_rows = 3,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D",
           labels_row = cytokines_normlog2FC_red_heatmap_data$subject_pre_post,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of all cytokines from multiplex assay")

Significant cells

cell_heatmap_data <- imputed_meta_table %>%
  unite("subject_pre_post_intervention", patient_id, pre_post_intervention, sep = "_", remove = FALSE) %>%
  dplyr::select(patient_id, subject_pre_post_intervention, pre_post, all_of(sig_cells_red$cell_type), all_of(sig_cells_yellow$cell_type), all_of(sig_cells_intervention$cell_type))


cell_heatmap <- 
  pheatmap(cell_heatmap_data[,-c(1:3)],
           scale = "column",
           cluster_rows = TRUE,
           cutree_rows = 6,
           clustering_distance_rows = "euclidean",
           clustering_distance_cols = "euclidean",
           clustering_method = "ward.D2",
           labels_row = cell_heatmap_data$subject_pre_post_intervention,
           color = colorRampPalette(c("#67a9cf", "#f7f7f7", "#ef8a62"))(16),
           main = "Heatmap of significant immuno outcomes across timepoints \nby paired T-tests \nBenjamoni-Hochberg corrected p-values > 0.05 \nC18 (-)")

Summary

  • There are no sequence effects for any of the outcomes

  • Carotenoids

    • Total lycopene levels increase significantly only after tomato-soy intervention.
  • Cytokines

    • No effects of carotenoids on cytokine levels (from mixed linear modeling analysis)
      • Once isoflavones and other phytochemicals are quantified, they will be investigated and it will be interesting to test interactions between the phytochemicals in mixed models.
    • IL-5, GM-CSF, and IL-12p70 has a significant reduction in levels only after red (tomato-soy) intervention
    • There are no significantly different cytokines when comparing plasma levels between post interventions.
  • Immune cell types

    • An NK cell type and MDSC monocytes significantly change (The NK cell type sig decreases, while MDSC monocytes increase) when comparing post-Yellow intervention to post-Red.
    • 8 immune cell types significantly increase after yellow intervention.
    • 3 immune cell types (including Naive B cells) significantly increase after red intervention.
    • Cell type #8 (EM CD8) significantly increased after consuming both juices.
LS0tCnRpdGxlOiAiU3RhdGlzdGljYWwgYW5hbHlzaXMgZm9yIGNhcm90ZW5vaWRzLCBjeXRva2luZXMsIGFuZCBpbW11bmUgY2VsbCBwb3B1bGF0aW9ucyIKYXV0aG9yOiAiTWFyaWEgU2hvbG9sYSIKZGF0ZTogIjIwMjMtMTItMDEiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgYW5jaG9yX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpCmBgYAoKCiMgSW50cm9kdWN0aW9uCgpTdGF0aXN0aWNhbCBhbmFseXNpcyBvZiBwbGFzbWEgY2Fyb3Rlbm9pZHMsIHBsYXNtYSBjeXRva2luZXMgYW5kIGltbXVuZSBjZWxscyBmcm9tIHJhbmRvbWl6ZWQgY3Jvc3Mtb3ZlciBVU0RBIGluZmxhbW1hdGlvbiBjbGluaWNhbCB0cmlhbC4gU3ViamVjdHMgY29uc3VtZWQgYm90aCBsb3cgbHljb3BlbmUgdG9tYXRvICh5ZWxsb3cpIGFuZCBoaWdoIGx5Y29wZW5lIHRvbWF0by1zb3kganVpY2VzIChyZWQpIGZvciA0IHdlZWtzIGVhY2guCgoKYGBge3IgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MDBweCIsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmNhcD0iQ3Jvc3NvdmVyIGNsaW5pY2FsIHRyaWFsIGRlc2lnbiBzdXBwbGVtZW50aW5nIGluZGl2aWR1YWxzIHdpdGggb2Jlc2l0eSAzNjAgbUwgb2YgYSBsb3cgY2Fyb3Rlbm9pZCB0b21hdG8ganVpY2Ugb3IgYSBoaWdoIGx5Y29wZW5lIHRvbWF0by1zb3kganVpY2UgZGFpbHkuIERhaWx5IHNlcnZpbmcgb2YgbG93IGNhcm90ZW5vaWQgdG9tYXRvIGp1aWNlIGNvbnNpc3RlZCBvZiB+MS41bWcgbHljb3BlbmUvZGF5IHdoaWxlIGhpZ2ggbHljb3BlbmUgdG9tYXRvLXNveSBqdWljZSBpbnRlcnZlbnRpb24gY29uc2lzdGVkIG9mIDU0IG1nIGx5Y29wZW5lL2RheSBpbiBhZGRpdGlvbiB0byAyMTAgbWcgdG90YWwgc295IGlzb2ZsYXZvbmVzL2RheS4ifQoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoInRvbWF0b3NveS1jbGluaWNhbC10cmlhbC13aGl0ZWJnLnBuZyIpCmBgYAoKIyBMb2FkIGxpYnJhcmllcwpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpICMgZGF0YSB3cmFuZ2xpbmcKbGlicmFyeShyZWFkeGwpICMgcmVhZCBpbiBleGNlbCBmaWxlcwpsaWJyYXJ5KGphbml0b3IpICMgY2xlYW4gdXAgbmFtZXMgaW4gZGF0YXNldApsaWJyYXJ5KGNvcnJyKSAjIGZpbmRpbmcgY29ycmVsYXRpb25zCmxpYnJhcnkocnN0YXRpeCkgIyBzdGF0cwpsaWJyYXJ5KGtuaXRyKSAjIGFlc3RoZXRpYyB0YWJsZSB2aWV3aW5nCmxpYnJhcnkocHVycnIpICMgY3JlYXRlIGZ1bmN0aW9ucwpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZ2d0ZXh0KQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShnZ2NvcnJwbG90KSAjIHRvIG1ha2UgY29yciBwbG90cwpsaWJyYXJ5KHBoZWF0bWFwKQpgYGAKCiMgUmVhZCBpbiBkYXRhCgpgYGB7ciwgcmVzdWx0cz0naGlkZSd9CiMgbG9hZCBkYXRhCm1ldGFfdGFibGUgPC0gcmVhZF9leGNlbCgiQ29tcGlsZWREYXRhX1Jlc3VsdHNfTWV0YS54bHN4IiwKICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0ID0gIm1ldGFkYXRhX2NvcnJlY3RlZF93aXRoc2VxdWVuY2UiKQoKIyBjbGVhbiB1cCB2YXJpYWJsZSBuYW1lcyAKbWV0YV90YWJsZSA8LSBjbGVhbl9uYW1lcyhtZXRhX3RhYmxlKQoKc3RyKG1ldGFfdGFibGUpCmBgYAoKCiMjIFdyYW5nbGUKCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KIyBjb252ZXJ0IHZhcmlhYmxlcyB0aGF0IHNob3VsZCBiZSBmYWN0b3JzIHRvIGZhY3RvcnMKbWV0YV90YWJsZSA8LSBtZXRhX3RhYmxlICU+JQogIG11dGF0ZShhY3Jvc3MoLmNvbHMgPSBjKCJwYXRpZW50X2lkIiwgInBlcmlvZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICJpbnRlcnZlbnRpb24iLCAiaW50ZXJ2ZW50aW9uX3dlZWsiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAicHJlX3Bvc3QiLCAic2V4IiwgInNlcXVlbmNlIiksCiAgICAgICAgICAgICAgICAuZm5zID0gYXMuZmFjdG9yKSkKCgojIHNvbWUgc3R1ZmYgY2FtZSBpbiBhcyBjaGFyYWN0ZXJzIGJ1dCBzaG91bGQgYmUgbnVtZXJpYwptZXRhX3RhYmxlIDwtIG1ldGFfdGFibGUgJT4lCiAgbXV0YXRlKGFjcm9zcyguY29scyA9IGMoImlsXzIiLCAiaWxfMTAiLCAiaWxfMTMiLCAiaWxfNCIpLAogICAgICAgICAgICAgICAgLmZucyA9IGFzLm51bWVyaWMpKQoKc3RyKG1ldGFfdGFibGUpCmBgYAoKCmBgYHtyfQojIGNoYW5naW5nIGZhY3RvciBsZXZlbHMgZm9yIHByZV9wb3N0Cm1ldGFfdGFibGUkcHJlX3Bvc3QgPC0gZmFjdG9yKG1ldGFfdGFibGUkcHJlX3Bvc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoInByZSIsICJwb3N0IikpCgpsZXZlbHMobWV0YV90YWJsZSRwcmVfcG9zdCkgIApgYGAKCgpgYGB7cn0KIyBDYWxjdWxhdGUgdG90YWxfY2lzX2x5YywgdG90YWxfbHljLCBhbmQgdG90YWxfY2Fyb3Rlbm9pZHMKbWV0YV90YWJsZSA8LSBtZXRhX3RhYmxlICU+JQogIHJlbmFtZShuNV9jaXNfbHljID0geDVfY2lzX2x5YykgJT4lCiAgbXV0YXRlKHRvdGFsX2Npc19seWMgPSBvdGhlcl9jaXNfbHljICsgbjVfY2lzX2x5YywKICAgICAgICAgdG90YWxfbHljID0gYWxsX3RyYW5zX2x5YyArIHRvdGFsX2Npc19seWMsCiAgICAgICAgIHRvdGFsX2Nhcm90ZW5vaWRzID0gbHV0ZWluICsgemVheGFudGhpbiArIGJfY3J5cHRveGFudGhpbiArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFfY2Fyb3RlbmUgKyBiX2Nhcm90ZW5lICsgdG90YWxfbHljKSAKYGBgCgoKIyBDYXJvdGVub2lkcwoKIyMgQWxsLXRyYW5zLWx5YyBsZXZlbHMKCmBgYHtyfQojIGxpbmUgcGxvdHMgZm9yIGVhY2ggc3ViamVjdCBhdCBlYWNoIHRpbWVwb2ludAptZXRhX3RhYmxlICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBpbnRlcnZlbnRpb25fd2VlaywgeSA9IGFsbF90cmFuc19seWMsIGNvbG9yID0gaW50ZXJ2ZW50aW9uKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBpbnRlcnZlbnRpb24pKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJncmF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWWVsbG93IiA9ICJnb2xkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXRpZW50X2lkKSwgc2NhbGVzID0gImZyZWVfeSIpICsgCiAgdGhlbWVfYncoKSArCiAgbGFicyh4ID0gIkludGVydmVudGlvbiBXZWVrIiwKICAgICAgIHkgPSAiQWxsLXRyYW5zLWx5Y29wZW5lIGxldmVscyAobm1vbC9MKSIsCiAgICAgICB0aXRsZSA9ICJBbGwtdHJhbnMtbHljb3BlbmUgbGV2ZWxzIGluIGVhY2ggcGF0aWVudCBiZWZvcmUvYWZ0ZXIgZWFjaCBpbnRlcnZlbnRpb24iKQpgYGAKCiMjIFRvdGFsIGNpcy1seWMgbGV2ZWxzCmBgYHtyfQojIGxpbmUgcGxvdHMgZm9yIGVhY2ggc3ViamVjdCBhdCBlYWNoIHRpbWVwb2ludAptZXRhX3RhYmxlICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBpbnRlcnZlbnRpb25fd2VlaywgeSA9IHRvdGFsX2Npc19seWMsIGNvbG9yID0gaW50ZXJ2ZW50aW9uKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBpbnRlcnZlbnRpb24pKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJncmF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWWVsbG93IiA9ICJnb2xkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXRpZW50X2lkKSkgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoeCA9ICJJbnRlcnZlbnRpb24gV2VlayIsCiAgICAgICB5ID0gIlRvdGFsIGNpcy1seWNvcGVuZSBsZXZlbHMgKG5tb2wvTCkiLAogICAgICAgdGl0bGUgPSAiVG90YWwgY2lzLWx5Y29wZW5lIGxldmVscyBpbiBlYWNoIHBhdGllbnQgYmVmb3JlL2FmdGVyIGVhY2ggaW50ZXJ2ZW50aW9uIikKYGBgCgojIyBUb3RhbCBseWMgbGV2ZWxzCgojIyMgbGluZXBsb3RzIAoKYGBge3J9CiMgbGluZSBwbG90cyBmb3IgZWFjaCBzdWJqZWN0IGF0IGVhY2ggdGltZXBvaW50Cm1ldGFfdGFibGUgJT4lIAogIGdncGxvdChhZXMoeCA9IGludGVydmVudGlvbl93ZWVrLCB5ID0gdG90YWxfbHljLCBjb2xvciA9IGludGVydmVudGlvbikpICsKICBnZW9tX3BvaW50KCkgKyAKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaW50ZXJ2ZW50aW9uKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJCYXNlbGluZSIgPSAiZ3JheSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlllbGxvdyIgPSAiZ29sZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkIiA9ICJ0b21hdG8xIikpICsKICBmYWNldF93cmFwKHZhcnMocGF0aWVudF9pZCksIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgdGhlbWVfYncoKSArCiAgbGFicyh4ID0gIkludGVydmVudGlvbiBXZWVrIiwKICAgICAgIHkgPSAiVG90YWwgbHljb3BlbmUgbGV2ZWxzIChubW9sL0wpIiwKICAgICAgIHRpdGxlID0gIlRvdGFsIGx5Y29wZW5lIGxldmVscyBpbiBlYWNoIHBhdGllbnQgYmVmb3JlL2FmdGVyIGVhY2ggaW50ZXJ2ZW50aW9uIikKYGBgCgoqbm90ZSogU3ViamVjdCA2MTEyIGhhcyBpbmNyZWFzZWQgdG90YWwgbHljb3BlbmUgbGV2ZWxzIGFmdGVyIHllbGxvdyBpbnRlcnZlbnRpb24uIEknbGwgcmVtb3ZlIHRoZW0gZnJvbSBzdGF0aXN0aWNhbCBhbmFseXNlcy4KCiMjIyBCb3hwbG90cwoKIyMjIyB3cmFuZ2xpbmcKCmBgYHtyfQojIGNyZWF0ZSBhIG1vcmUgc3BlY2lmaWMgcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uIGNvbHVtbgptZXRhX3RhYmxlX2VkaXRlZCA8LSBtZXRhX3RhYmxlICU+JQogIHVuaXRlKGNvbCA9ICJwcmVfcG9zdF9pbnRlcnZlbnRpb24iLAogICAgICAgIGMoInByZV9wb3N0IiwiaW50ZXJ2ZW50aW9uIiksCiAgICAgICAgc2VwID0gIl8iLAogICAgICAgIHJlbW92ZSA9IEZBTFNFKQoKIyBtYWtlIHByZV9wb3N0X2ludGVydmVudGlvbiBjb2x1bW4gZmFjdG9ycwptZXRhX3RhYmxlX2VkaXRlZCRwcmVfcG9zdF9pbnRlcnZlbnRpb24gPC0gYXMuZmFjdG9yKG1ldGFfdGFibGVfZWRpdGVkJHByZV9wb3N0X2ludGVydmVudGlvbikKCiMgcmVsZXZlbCBmYWN0b3IgY29sdW1ucwptZXRhX3RhYmxlX2VkaXRlZCRwcmVfcG9zdF9pbnRlcnZlbnRpb24gPC0gZmFjdG9yKG1ldGFfdGFibGVfZWRpdGVkJHByZV9wb3N0X2ludGVydmVudGlvbiwgbGV2ZWxzID0gYygicHJlX1llbGxvdyIsICJwb3N0X1llbGxvdyIsICJwcmVfUmVkIiwgInBvc3RfUmVkIikpCgptZXRhX3RhYmxlX2VkaXRlZCRpbnRlcnZlbnRpb24gPC0gZmFjdG9yKG1ldGFfdGFibGVfZWRpdGVkJGludGVydmVudGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJCYXNlbGluZSIsIlllbGxvdyIsICJSZWQiKSkKCmBgYAoKCmBgYHtyfQojIG1ha2UgbGVnZW5kIHRpdGxlCmxlZ2VuZHRpdGxlX3BwaW50ZXJ2ZW50aW9uIDwtICJUaW1lcG9pbnQiCgoKIyBsYWJlbHMKbGFic19wcGludGVydmVudGlvbiA8LSBjKCJwcmUgY29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAicG9zdCBjb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICJwcmUgVG9tYXRvLVNveSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAicG9zdCBUb21hdG8tU295IikKYGBgCgoKIyMjIyBmaWd1cmUKYGBge3J9Cm1ldGFfdGFibGVfZWRpdGVkICU+JSAKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uICE9ICJCYXNlbGluZSIpICU+JQogIGdncGxvdChhZXMoeCA9IGludGVydmVudGlvbiwgeSA9IHRvdGFsX2x5YywgZmlsbCA9IHByZV9wb3N0X2ludGVydmVudGlvbikpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxlZ2VuZHRpdGxlX3BwaW50ZXJ2ZW50aW9uLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInByZV9SZWQiID0gIiNGRjk5NjYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvc3RfUmVkIiA9ICIjRkYzMzAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmVfWWVsbG93IiA9ICIjRkZGRjk5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3N0X1llbGxvdyIgPSAieWVsbG93IiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gbGFic19wcGludGVydmVudGlvbikgKwogIHRoZW1lX2NsZWFuKCkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJUb3RhbCBseWNvcGVuZSBsZXZlbHMgKG5tb2wvTCkiLAogICAgICAgdGl0bGUgPSAiVG90YWwgbHljb3BlbmUgbGV2ZWxzIGJlZm9yZS9hZnRlciBqdWljZSBpbnRlcnZlbnRpb25zIikKYGBgCgoKCgoKYGBge3IsIGZpZy53aWR0aD0xMn0KIyBnZ3B1YnIgdG8gbWFrZSBwdWIgcmVhZHkgcGxvdAoodG90YWxfbHljX2xldmVscyA8LSBtZXRhX3RhYmxlX2VkaXRlZCAlPiUgCiAgICBmaWx0ZXIoaW50ZXJ2ZW50aW9uICE9ICJCYXNlbGluZSIpICU+JQogIGdncGFpcmVkKHggPSAicHJlX3Bvc3QiLCB5ID0gInRvdGFsX2x5YyIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgbGluZS5jb2xvciA9ICJncmF5IiwgbGluZS5zaXplID0gMSwgZmFjZXQuYnkgPSAiaW50ZXJ2ZW50aW9uIiwgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBwYW5lbC5sYWJzID0gbGlzdChpbnRlcnZlbnRpb24gPSBjKCIiLCAiIiwgIiIpKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlJlZCIgPSAidG9tYXRvMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWWVsbG93IiA9ICJ5ZWxsb3cxIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJUb21hdG8tU295IiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIGxpbmV3aWR0aCA9IDAuMTUpICsKICB0aGVtZV9jbGVhbihiYXNlX3NpemUgPSAxOCwgYmFzZV9mYW1pbHkgPSAic2FucyIpICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAibm1vbC9MIHBsYXNtYSIsCiAgICAgICB0aXRsZSA9ICJDb25jZW50cmF0aW9uIG9mIEx5Y29wZW5lIiwKICAgICAgIHN1YnRpdGxlID0gIiIpKQpgYGAKCiMjIyMgZXhwb3J0CmBgYHtyLCBldmFsPUZBTFNFfQpnZ3NhdmUoZmlsZW5hbWUgPSAiL1VzZXJzL21hcmlhc2hvbG9sYS9Eb2N1bWVudHMvR2l0SHViL1VTREEtSW5mbGFtbWF0aW9uLU1ldGFib2xvbWljcy9QbG90cy90b3RhbC1seWMtcmVkLWFuZC15ZWxsb3ctYm94cGxvdHMuc3ZnIiwgcGxvdCA9IHRvdGFsX2x5Y19sZXZlbHMsIHdpZHRoID0gMTIpCmBgYAoKCiMjIyBEZXNjcmlwdGl2ZSBzdGF0cwoKIyMjIyB3cmFuZ2xlCmBgYHtyfQojIGNvbnZlcnQgbWV0YV90YWJsZV9lZGl0ZWQgdG8gbG9uZyBmb3JtYXQgZm9yIHRvdGFsIGx5Y29wZW5lCm1ldGFfdGFibGVfbHljX2xvbmcgPC0gbWV0YV90YWJsZV9lZGl0ZWQgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSB0b3RhbF9seWMsCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInRvdGFsX2x5Y29wZW5lIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIm5tb2xfcGVyX0wiKQpgYGAKCgojIyMjIEF2Zy9zdGQgZGV2CgojIyMjIyB0b21zb3kKYGBge3J9Cm1ldGFfdGFibGVfbHljX2xvbmcgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiUmVkIikgJT4lCiAgZ3JvdXBfYnkocHJlX3Bvc3QpICU+JQogIHN1bW1hcml6ZShtZWFuID0gbWVhbihubW9sX3Blcl9MKSwKICAgICAgICAgICAgc3RkZXYgPSBzZChubW9sX3Blcl9MKSkKYGBgCgojIyMjIyB5ZWxsb3cKYGBge3J9Cm1ldGFfdGFibGVfbHljX2xvbmcgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiWWVsbG93IikgJT4lCiAgZ3JvdXBfYnkocHJlX3Bvc3QpICU+JQogIHN1bW1hcml6ZShtZWFuID0gbWVhbihubW9sX3Blcl9MKSwKICAgICAgICAgICAgc3RkZXYgPSBzZChubW9sX3Blcl9MKSkKYGBgCgojIyMjIE1lYW4gZm9sZCBjaGFuZ2VzCmBgYHtyfQpseWNfc3Vic2V0IDwtIG1ldGFfdGFibGVfbHljX2xvbmcgJT4lCiAgc2VsZWN0KHBhdGllbnRfaWQsIHByZV9wb3N0X2ludGVydmVudGlvbiwgbm1vbF9wZXJfTCkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByZV9wb3N0X2ludGVydmVudGlvbiwKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG5tb2xfcGVyX0wpICU+JQogIG11dGF0ZShyZWRfRkMgPSBwb3N0X1JlZC9wcmVfUmVkLAogICAgICAgICB5ZWxsb3dfRkMgPSBwb3N0X1llbGxvdy9wcmVfWWVsbG93KQoKbHljX3N1YnNldCAlPiUKICBzdW1tYXJpemUobWVhbl9yZWRfRkMgPSBtZWFuKHJlZF9GQyksCiAgICAgICAgICAgIG1lYW5feWVsbG93X0ZDID0gbWVhbih5ZWxsb3dfRkMpKQpgYGAKCiMjIENvbXBhcmlzb24gc3RhdHMKCkZpcnN0LCBJIG5lZWQgdG8gcmVtb3ZlIHN1YmplY3QgNjExMiBmcm9tIHRoZSB5ZWxsb3cgaW50ZXJ2ZW50aW9uLCBzaW5jZSB0aGVpciB0b3RhbCBseWNvcGVuZSBsZXZlbHMgaXMgdGhlIG9ubHkgb25lIGluY3JlYXNpbmcgcG9zdC1ZZWxsb3cKCmBgYHtyfQpzdWJqNjExMl95ZWxsb3cgPC0gbWV0YV90YWJsZV9seWNfbG9uZyAlPiUKICBmaWx0ZXIocGF0aWVudF9pZCA9PSA2MTEyKSAlPiUKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uID09ICJZZWxsb3ciKQoKbWV0YV90YWJsZV9seWNfbG9uZ19ybV9vdXRsaWVyIDwtIGFudGlfam9pbihtZXRhX3RhYmxlX2x5Y19sb25nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJqNjExMl95ZWxsb3cpCiAgCmBgYAoKIyMjIE5vcm1hbGl0eSBjaGVja3MKClBsb3QgaGlzdG9ncmFtCmBgYHtyfQpnZ2hpc3RvZ3JhbShtZXRhX3RhYmxlX2x5Y19sb25nX3JtX291dGxpZXIkbm1vbF9wZXJfTCwgYmlucyA9IDQwKQpgYGAKClNoYXBpcm8ncyBub3JtYWxpdHkgdGVzdAoKYGBge3J9CiMgc2hhcGlybyBub3JtYWxpdHkgdGVzdCBmb3IgdG90YWwgbHljb3BlbmUuIGZvciBwcmUgeWVsbG93LCBwb3N0IHllbGxvdywgcHJlIHJlZCBhbmQgcG9zdCByZWQKbWV0YV90YWJsZV9seWNfbG9uZ19ybV9vdXRsaWVyICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gIT0gIkJhc2VsaW5lIikgJT4lCiAgZ3JvdXBfYnkocHJlX3Bvc3RfaW50ZXJ2ZW50aW9uKSAlPiUKICBzaGFwaXJvX3Rlc3QodmFycyA9ICJubW9sX3Blcl9MIikKYGBgClAgPiAwLjA1IGZvciBhbGwgNCBncm91cHMsIHN1Z2dlc3RpbmcgZGF0YSBoZXJlIGlzIG5vcm1hbC4KCiMjIyBQYWlyZWQgdC10ZXN0CmBgYHtyfQpjb21wYXJlX21lYW5zKG5tb2xfcGVyX0wgfiBwcmVfcG9zdCwgbWV0YV90YWJsZV9seWNfbG9uZ19ybV9vdXRsaWVyLCBtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgZ3JvdXAuYnkgPSAiaW50ZXJ2ZW50aW9uIikKYGBgCgojIyMgQm94cGxvdApgYGB7cn0KKGx5Y19icF9zdGF0c19ub091dGxpZXIgPC0gbWV0YV90YWJsZV9seWNfbG9uZ19ybV9vdXRsaWVyICU+JSAKICAgZmlsdGVyKGludGVydmVudGlvbiAhPSAiQmFzZWxpbmUiKSAlPiUKICBnZ3BhaXJlZCh4ID0gInByZV9wb3N0IiwgeSA9ICJubW9sX3Blcl9MIiwgZmlsbCA9ICJpbnRlcnZlbnRpb24iLCAKICAgICAgICAgICBsaW5lLmNvbG9yID0gImdyYXkiLCAKICAgICAgICAgICBsaW5lLnNpemUgPSAxLCAKICAgICAgICAgICBmYWNldC5ieSA9ICJpbnRlcnZlbnRpb24iLCAKICAgICAgICAgICBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UsIHBhbmVsLmxhYnMgPSBsaXN0KGludGVydmVudGlvbiA9IGMoIiIsICIiLCAiIikpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiUmVkIiA9ICJ0b21hdG8xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJZZWxsb3ciID0gInllbGxvdzEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlRvbWF0by1Tb3kiKSwKICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkludGVydmVudGlvbiIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gcGF0aWVudF9pZCksIGNvbG91ciA9ICJncmF5IiwgbGluZXdpZHRoID0gMC4xNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJubW9sL0wgcGxhc21hIiwKICAgICAgIHRpdGxlID0gIkNvbmNlbnRyYXRpb24gb2YgTHljb3BlbmUiLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsIHBhaXJlZCA9IFRSVUUpICkKYGBgCgpUb3RhbCBseWNvcGVuZSBsZXZlbHMgYXJlIHNpZ25pZmljYW50bHkgaW5jcmVhc2luZyBvbmx5IGFmdGVyIHBvc3QtUmVkIGludGVydmVudGlvbgoKIyMjIyBleHBvcnQKYGBge3IsIGV2YWw9RkFMU0V9Cmdnc2F2ZShmaWxlbmFtZSA9ICJQbG90cy90b3RhbC1seWMtcmVkLXllbGxvdy1ib3hwbG90cy1zdGF0cy1ub091dGxpZXIuc3ZnIiwgcGxvdCA9IGx5Y19icF9zdGF0c19ub091dGxpZXIsIHdpZHRoID0gMTIpCmBgYAoKIyBNaXNzaW5nIGRhdGEKCgpgYGB7cn0KIyBjYWxjdWxhdGUgaG93IG1hbnkgTkFzIHRoZXJlIGFyZSBwZXIgY3l0b2tpbmUgaW4gd2hvbGUgZGF0YSBzZXQKY29udGFpbnNOQXNfY3l0b2tpbmVzIDwtIG1ldGFfdGFibGVfZWRpdGVkICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gIT0gIkJhc2VsaW5lIikgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBpZl9uZzppbF80LAogICAgICAgICAgICAgICBuYW1lc190byA9ICJjeXRva2luZSIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjeXRvX2NvbmNfcGdfbWwiKSAlPiUKICBncm91cF9ieShjeXRva2luZSwgcGF0aWVudF9pZCkgJT4lCiAgY291bnQoaXMubmEoY3l0b19jb25jX3BnX21sKSkgJT4lCiAgZmlsdGVyKGBpcy5uYShjeXRvX2NvbmNfcGdfbWwpYCA9PSBUUlVFKQoKa2FibGUoY29udGFpbnNOQXNfY3l0b2tpbmVzKQpgYGAKCgpgYGB7cn0KIyBjYWxjdWxhdGUgaG93IG1hbnkgTkFzIHRoZXJlIGFyZSBwZXIgY3l0b2tpbmUgaW4gd2hvbGUgZGF0YSBzZXQKY29udGFpbnNOQXNfY2VsbHMgPC0gbWV0YV90YWJsZV9lZGl0ZWQgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiAhPSAiQmFzZWxpbmUiKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IHN0YXJ0c193aXRoKCJ4IiksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImNlbGxfdHlwZSIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjZWxsX3ZhbHVlIikgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24pICU+JQogIGNvdW50KGlzLm5hKGNlbGxfdmFsdWUpKSAlPiUKICBmaWx0ZXIoYGlzLm5hKGNlbGxfdmFsdWUpYCA9PSBUUlVFKQoKa2FibGUoY29udGFpbnNOQXNfY2VsbHMpCmBgYAoKYGBge3J9CiMgaW1wdXRlIGFueSBtaXNzaW5nIHZhbHVlcyBieSByZXBsYWNpbmcgdGhlbSB3aXRoIDEvMiBvZiB0aGUgbG93ZXN0IGNvbmNlbnRyYXRpb24gdmFsdWUgb2YgYSBjeXRva2luZSAoaS5lLiBpbiBhIHJvdykuCmltcHV0ZWRfbWV0YV90YWJsZSA8LSBtZXRhX3RhYmxlX2VkaXRlZCAlPiUKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uICE9ICJCYXNlbGluZSIpCgppbXB1dGVkX21ldGFfdGFibGVbLDExOjI1XSA8LSBsYXBwbHkoaW1wdXRlZF9tZXRhX3RhYmxlWywxMToyNV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSBpZmVsc2UoaXMubmEoeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oeCwgbmEucm0gPSBUUlVFKS8yLCB4KSkKCmRpbShpbXB1dGVkX21ldGFfdGFibGUpCmBgYAoKIyBDeXRva2luZXMKCmBgYHtyfQojIGNvbnZlcnQgY3l0b2tpbmVzIGZyb20gd2lkZSB0byBsb25nCmN5dG9raW5lc19sb25nIDwtIGltcHV0ZWRfbWV0YV90YWJsZVstYygyNjo4MildICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gaWZfbmc6aWxfNCwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiY3l0b2tpbmUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY3l0b19jb25jX3BnX21sIikKYGBgCgoKTGV0J3MgcmVtb3ZlIHN1YmplY3QgZGF0YSBwb2ludHMgZm9yIHN1YmplY3QgNjExMidzIHllbGxvdyBpbnRlcnZlbnRpb24gZmlyc3QgKHRoZWlyIHRvdGFsIGx5Y29wZW5lIGxldmVscyBpbmNyZWFzZWQgcG9zdC15ZWxsb3cgaW50ZXJ2ZW50aW9uKQoKYGBge3J9CmN5dG9raW5lc19ub091dGxpZXJfbG9uZyA8LSBhbnRpX2pvaW4oY3l0b2tpbmVzX2xvbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViajYxMTJfeWVsbG93KQpgYGAKCgpBZnRlciB0ZXN0aW5nIHNldmVyYWwgbWl4ZWQgbGluZWFyIG1vZGVscywgdGhlIGJlc3QgbW9kZWwgdHVybmVkIG91dCB0byBoYXZlIHByZV9wb3N0IGFzIGEgZml4ZWQgdmFyaWFibGUgYW5kIHBhdGllbnRfaWQgYXMgcmFuZG9tIGVmZmVjdC4gQ2Fyb3Rlbm9pZHMgYWRkZWQgbm8gc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBlZmZlY3QgdG8gdGhlIG1vZGVsLCBzdWdnZXN0aW5nIHRoYXQgY2Fyb3Rlbm9pZHMgbWF5IG5vdCBjb250cmlidXRlIHRvIGN5dG9raW5lIGxldmVscy4gV2UgZGVjaWRlZCB0byBtb3ZlIG9uIHdpdGggcGFpcmVkIG1lYW4gY29tcGFyaXNvbnMgZm9yIGVhY2ggZ3JvdXAuIE1heSByZXZpc2l0IG1peGVkIGxpbmVhciBtb2RlbGluZyB0byBzZWUgaWYgc2lnbmlmaWNhbnQgbWV0YWJvbGl0ZXMgZnJvbSBtZXRhYm9sb21pY3MgYW5hbHlzZXMgYWZmZWN0IGltbXVuZSBvdXRjb21lcyAoaS5lLiBjeXRva2luZSBjb25jZW50cmF0aW9ucyBhbmQgaW1tdW5lIGNlbGwgcG9wdWxhdGlvbnMpLgoKIyMgTm9ybWFsaXR5IGNoZWNrCgpgYGB7cn0KY3l0b2tpbmVzX25vT3V0bGllcl9sb25nICU+JQogIGdyb3VwX2J5KGN5dG9raW5lKSAlPiUKICBzaGFwaXJvX3Rlc3QoY3l0b19jb25jX3BnX21sKQpgYGAKCkRhdGEgaXMgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCBzbyB3aWxsIHVzZSBub25wYXJhbWV0cmljIHBhaXJlZCB0ZXN0cyBmb3IgdGhlIG1lYW4gY29tcGFyaXNvbnMuCgojIyBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0cwoKIyMjIENhcnJ5b3ZlciBlZmZlY3RzPwoKRmlyc3QsIGxldCdzIHRlc3QgZm9yIHNlcXVlbmNlIGVmZmVjdHMuIFdlIGRvbid0IGV4cGVjdCB0byBoYXZlIHRoaXMgcHJvYmxlbSBzaW5jZSB0aGUgcGFydGljaXBhbnRzIGRpZCBhIDQtd2VlayB3YXNob3V0IHBlcmlvZCAobm8gdG9tYXRvL2x5Y29wZW5lIG9yIHNveSBpc29mbGF2b25lLWNvbnRhaW5pbmcgZm9vZHMpLiBUaGlzIHNob3VsZCBoYXZlIGJlZW4gc3VmZmljaWVudCBlbm91Z2ggZm9yIHRoZSBpbnRlcnZlbnRpb24gdG8gbm90IGhhdmUgbGluZ2VyaW5nIGVmZmVjdHMgb24gY3l0b2tpbmUgbGV2ZWxzLgoKCgpgYGB7cn0KKHdpbGNveF9jeXRvX3NlcWVmZmVjdHMgPC0gY3l0b2tpbmVzX2xvbmcgJT4lCiAgIGZpbHRlcihwcmVfcG9zdCA9PSAicG9zdCIpICU+JQogICBncm91cF9ieShjeXRva2luZSkgJT4lCiAgIHdpbGNveF90ZXN0KGN5dG9fY29uY19wZ19tbCB+IHNlcXVlbmNlLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiLCBkZXRhaWxlZCA9IFRSVUUpKQpgYGAKCkZvciBldmVyeSBjeXRva2luZSwgc2VxdWVuY2UgZG9lcyBub3Qgc2lnbmlmaWNhbnRseSBlZmZlY3QgdGhlIG91dGNvbWUuIFRoZXJlZm9yZSB3ZSBjYW4gY29udGludWUgdG8gYXNzdW1lIHRoZXJlIGFyZSBubyBzZXF1ZW5jZSBlZmZlY3RzLgoKIyMjIEZyaWVkbWFuIHRlc3QKCk5vbi1wYXJhbWV0cmljIGFsdGVybmF0aXZlIHRvIHJlcGVhdGVkIG1lYXN1cmVzIEFOT1ZBCgpgYGB7ciwgZXZhbD1GQUxTRX0KI25vdCB3b3JraW5nIGZvciBtZQpmcmllZG1hbl90ZXN0IDwtIGN5dG9raW5lc19sb25nICU+JQogIHNlbGVjdChwYXRpZW50X2lkLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIGN5dG9raW5lLCBjeXRvX2NvbmNfcGdfbWwpICU+JQogIGZyaWVkbWFuX3Rlc3QoY3l0b19jb25jX3BnX21sIH4gcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uIHwgcGF0aWVudF9pZCkKYGBgCgoKIyMjIFllbGxvdyB0cnQgZWZmZWN0cwoKQ29tcGFyaW5nIHByZS0gdG8gcG9zdC15ZWxsb3cgKGxvdyBjYXJvdGVub2lkKSBpbnRlcnZlbnRpb24KCmBgYHtyfQood2lsY294X2N5dG9feWVsbG93IDwtIGN5dG9raW5lc19ub091dGxpZXJfbG9uZyAlPiUKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uID09ICJZZWxsb3ciKSAlPiUKICBncm91cF9ieShjeXRva2luZSkgJT4lCiAgd2lsY294X3Rlc3QoY3l0b19jb25jX3BnX21sIH4gcHJlX3Bvc3QsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIGRldGFpbGVkID0gVFJVRSkpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCihzaWdfY3l0b2tpbmVzX3llbGxvdyA8LSB3aWxjb3hfY3l0b195ZWxsb3cgJT4lCiAgZmlsdGVyKHAgPCAwLjA1KSkKYGBgCgojIyMgUmVkIHRydCBlZmZlY3RzCgpDb21wYXJpbmcgcHJlLSB0byBwb3N0LXJlZCAodG9tYXRvLXNveSkgaW50ZXJ2ZW50aW9uCgpgYGB7cn0KKHdpbGNveF9jeXRvX3JlZCA8LSAgY3l0b2tpbmVzX25vT3V0bGllcl9sb25nICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlJlZCIpICU+JQogIGdyb3VwX2J5KGN5dG9raW5lKSAlPiUKICB3aWxjb3hfdGVzdChjeXRvX2NvbmNfcGdfbWwgfiBwcmVfcG9zdCwgcGFpcmVkID0gVFJVRSwgcC5hZGp1c3QubWV0aG9kID0gIkJIIiwgZGV0YWlsZWQgPSBUUlVFKSkKYGBgCgpgYGB7cn0KIyBleHRyYWN0IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgY3l0b2tpbmVzIAooc2lnX2N5dG9raW5lc19yZWQgPC0gd2lsY294X2N5dG9fcmVkICU+JQogIGZpbHRlcih3aWxjb3hfY3l0b19yZWQkcCA8IDAuMDUpKQpgYGAKCiogVGhlcmUgYXJlIDMgY3l0b2tpbmVzIChHTS1DU0YsIElMLTEycDcwLCBhbmQgSUwtNSkgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBwcmUgYW5kIHBvc3QtUmVkIGludGVydmVudGlvbnMgb25seS4gTGV0cyBpbnZlc3RpZ2F0ZS4gCgojIyMjIEdNLUNTRgoKIyMjIyMgYm94cGxvdHMKYGBge3J9CmN5dG9raW5lc19sb25nICU+JSAKICBmaWx0ZXIoY3l0b2tpbmUgPT0gImdtX2NzZiIpICU+JQogIGdncGFpcmVkKHggPSAicHJlX3Bvc3QiLCB5ID0gImN5dG9fY29uY19wZ19tbCIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgZmFjZXQuYnkgPSAiaW50ZXJ2ZW50aW9uIiwgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBwYW5lbC5sYWJzID0gbGlzdChpbnRlcnZlbnRpb24gPSBjKCIiLCAiIiwgIiIpKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlJlZCIgPSAidG9tYXRvMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWWVsbG93IiA9ICJ5ZWxsb3cxIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJUb21hdG8tU295IiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjE1KSArCiAgdGhlbWVfY2xlYW4oYmFzZV9zaXplID0gMTgsIGJhc2VfZmFtaWx5ID0gInNhbnMiKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gInBnL21MIHBsYXNtYSIsCiAgICAgICB0aXRsZSA9ICJDb25jZW50cmF0aW9uIG9mIEdNLUNTRiIsCiAgICAgICBzdWJ0aXRsZSA9ICIiKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIpCgpgYGAKCgpgYGB7cn0KY3l0b2tpbmVzX2xvbmcgJT4lIAogIGZpbHRlcihjeXRva2luZSA9PSAiZ21fY3NmIikgJT4lCiAgZmlsdGVyKHBhdGllbnRfaWQgIT0gNjEwMikgJT4lICM2MTAyIGhhcyByZWFsbHkgaGlnaCBsZXZlbHMgc28gbGV0J3Mgc2VlIHdoYXQgdGhlIGRhdGEgbG9va3MgbGlrZSB3aXRob3V0IHRoZW0KICBnZ3BhaXJlZCh4ID0gInByZV9wb3N0IiwgeSA9ICJjeXRvX2NvbmNfcGdfbWwiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gImludGVydmVudGlvbiIsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgcGFuZWwubGFicyA9IGxpc3QoaW50ZXJ2ZW50aW9uID0gYygiIiwgIiIsICIiKSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJSZWQiID0gInRvbWF0bzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlllbGxvdyIgPSAieWVsbG93MSIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiVG9tYXRvLVNveSIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW50ZXJ2ZW50aW9uIikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBwYXRpZW50X2lkKSwgY29sb3VyID0gImdyYXkiLCBzaXplID0gMC4xNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJwZy9tTCBwbGFzbWEiLAogICAgICAgdGl0bGUgPSAiQ29uY2VudHJhdGlvbiBvZiBHTS1DU0YiLAogICAgICAgc3VidGl0bGUgPSAiIikKCmBgYAoKIyMjIyMgbGluZXBsb3RzCgpgYGB7cn0KbWV0YV90YWJsZSAlPiUgCiAgZmlsdGVyKGludGVydmVudGlvbiAhPSAiQmFzZWxpbmUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwcmVfcG9zdCwgeSA9IGdtX2NzZiwgY29sb3IgPSBpbnRlcnZlbnRpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGludGVydmVudGlvbikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiWWVsbG93IiA9ICJnb2xkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkIiA9ICJ0b21hdG8xIikpICsKICBmYWNldF93cmFwKHZhcnMocGF0aWVudF9pZCksIHNjYWxlcyA9ICJmcmVlX3kiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIkdNLUNTRiBjb25jIChwZy9tTCkiLAogICAgICAgdGl0bGUgPSAiR00tQ1NGIGxldmVscyBpbiBlYWNoIHBhdGllbnQgcHJlLSBhbmQgcG9zdC0gcmVkIGFuZCB5ZWxsb3cgaW50ZXJ2ZW50aW9uIikKYGBgCgojIyMjIElMLTEycDcwCgojIyMjIyBib3hwbG90cwpgYGB7cn0KY3l0b2tpbmVzX2xvbmcgJT4lIAogIGZpbHRlcihjeXRva2luZSA9PSAiaWxfMTJwNzAiKSAlPiUKICBnZ3BhaXJlZCh4ID0gInByZV9wb3N0IiwgeSA9ICJjeXRvX2NvbmNfcGdfbWwiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gImludGVydmVudGlvbiIsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgcGFuZWwubGFicyA9IGxpc3QoaW50ZXJ2ZW50aW9uID0gYygiIiwgIiIsICIiKSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJSZWQiID0gInRvbWF0bzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlllbGxvdyIgPSAieWVsbG93MSIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiVG9tYXRvLVNveSIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW50ZXJ2ZW50aW9uIikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBwYXRpZW50X2lkKSwgY29sb3VyID0gImdyYXkiLCBzaXplID0gMC4xNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJwZy9tTCBwbGFzbWEiLAogICAgICAgdGl0bGUgPSAiQ29uY2VudHJhdGlvbiBvZiBJTC0xMnA3MCIsCiAgICAgICBzdWJ0aXRsZSA9ICIiKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIpCgpgYGAKCgpgYGB7cn0KY3l0b2tpbmVzX2xvbmcgJT4lIAogIGZpbHRlcihjeXRva2luZSA9PSAiaWxfMTJwNzAiKSAlPiUKICBmaWx0ZXIocGF0aWVudF9pZCAhPSA2MTAyKSAlPiUgIyB0YWtlIG9mZiBzdWJqZWN0IDYxMDIgc2luY2UgdGhlaXIgbGV2ZWxzIGFyZSBzbyBoaWdoCiAgZ2dwYWlyZWQoeCA9ICJwcmVfcG9zdCIsIHkgPSAiY3l0b19jb25jX3BnX21sIiwgZmlsbCA9ICJpbnRlcnZlbnRpb24iLCBmYWNldC5ieSA9ICJpbnRlcnZlbnRpb24iLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UsIHBhbmVsLmxhYnMgPSBsaXN0KGludGVydmVudGlvbiA9IGMoIiIsICIiLCAiIikpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiUmVkIiA9ICJ0b21hdG8xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJZZWxsb3ciID0gInllbGxvdzEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlRvbWF0by1Tb3kiKSwKICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkludGVydmVudGlvbiIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gcGF0aWVudF9pZCksIGNvbG91ciA9ICJncmF5Iiwgc2l6ZSA9IDAuMTUpICsKICB0aGVtZV9jbGVhbihiYXNlX3NpemUgPSAxOCwgYmFzZV9mYW1pbHkgPSAic2FucyIpICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAicGcvbUwgcGxhc21hIiwKICAgICAgIHRpdGxlID0gIkNvbmNlbnRyYXRpb24gb2YgSUwtMTJwNzAiLAogICAgICAgc3VidGl0bGUgPSAiIikKYGBgCgoKIyMjIyMgbGluZXBsb3RzCgpgYGB7cn0KbWV0YV90YWJsZSAlPiUgCiAgZmlsdGVyKGludGVydmVudGlvbiAhPSAiQmFzZWxpbmUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwcmVfcG9zdCwgeSA9IGlsXzEycDcwLCBjb2xvciA9IGludGVydmVudGlvbikpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaW50ZXJ2ZW50aW9uKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJZZWxsb3ciID0gImdvbGQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXRpZW50X2lkKSwgc2NhbGVzID0gImZyZWVfeSIpICsgCiAgdGhlbWVfY2xhc3NpYygpICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAiSUwtMTJwNzAgY29uYyAocGcvbUwpIiwKICAgICAgIHRpdGxlID0gIklMLTEycDcwIGxldmVscyBpbiBlYWNoIHBhdGllbnQgcHJlLSBhbmQgcG9zdC0gcmVkIGFuZCB5ZWxsb3cgaW50ZXJ2ZW50aW9uIikKYGBgCgoKCiMjIyMgSUwtNQoKIyMjIyMgYm94cGxvdHMKYGBge3J9CmN5dG9raW5lc19sb25nICU+JSAKICBmaWx0ZXIoY3l0b2tpbmUgPT0gImlsXzUiKSAlPiUKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uICE9ICJCYXNlbGluZSIpICU+JQogIGdncGFpcmVkKHggPSAicHJlX3Bvc3QiLCB5ID0gImN5dG9fY29uY19wZ19tbCIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgZmFjZXQuYnkgPSAiaW50ZXJ2ZW50aW9uIiwgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBwYW5lbC5sYWJzID0gbGlzdChpbnRlcnZlbnRpb24gPSBjKCIiLCAiIiwgIiIpKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlJlZCIgPSAidG9tYXRvMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWWVsbG93IiA9ICJ5ZWxsb3cxIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJUb21hdG8tU295IiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjE1KSArCiAgdGhlbWVfY2xlYW4oYmFzZV9zaXplID0gMTgsIGJhc2VfZmFtaWx5ID0gInNhbnMiKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gInBnL21MIHBsYXNtYSIsCiAgICAgICB0aXRsZSA9ICJDb25jZW50cmF0aW9uIG9mIElMLTUiLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiKQoKYGBgCgoKIyMjIyMgbGluZXBsb3RzCgpgYGB7cn0KbWV0YV90YWJsZSAlPiUgCiAgZmlsdGVyKGludGVydmVudGlvbiAhPSAiQmFzZWxpbmUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwcmVfcG9zdCwgeSA9IGlsXzUsIGNvbG9yID0gaW50ZXJ2ZW50aW9uKSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBpbnRlcnZlbnRpb24pKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlllbGxvdyIgPSAiZ29sZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZCIgPSAidG9tYXRvMSIpKSArCiAgZmFjZXRfd3JhcCh2YXJzKHBhdGllbnRfaWQpLCBzY2FsZXMgPSAiZnJlZV95IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJJTC01IGNvbmMgKHBnL21MKSIsCiAgICAgICB0aXRsZSA9ICJJTC01IGxldmVscyBpbiBlYWNoIHBhdGllbnQgcHJlLSBhbmQgcG9zdC0gcmVkIGFuZCB5ZWxsb3cgaW50ZXJ2ZW50aW9uIikKYGBgCgojIyMjIGZvbGQgY2hhbmdlCgpMZXQncyBsb29rIGF0IHRoZSBhdmVyYWdlIGZvbGQgY2hhbmdlIGZvciBzaWduaWZpY2FudGx5IGNoYW5naW5nIGNlbGxzIGluIHllbGxvdy4gV2UnbGwgbG9vayBhdCB0aGUgYXZnIGZvbGQgY2hhbmdlIGNvbXBhcmluZyBwcmUgdG8gcG9zdCB5ZWxsb3csIHByZSB0byBwb3N0IFJlZCwgYW5kIHBvc3QtaW50ZXJ2ZW50aW9uIGNvbXBhcmlzb24uCgpgYGB7cn0KCnJlZF9zaWdjeXRva2luZXNfc3Vic2V0IDwtIGN5dG9raW5lc19ub091dGxpZXJfbG9uZyAlPiUKICBmaWx0ZXIoY3l0b2tpbmUgJWluJSBzaWdfY3l0b2tpbmVzX3JlZCRjeXRva2luZSklPiUKICBzZWxlY3QocGF0aWVudF9pZCwgcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCBjeXRva2luZSwgY3l0b19jb25jX3BnX21sKSAlPiUKICBncm91cF9ieShjeXRva2luZSkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByZV9wb3N0X2ludGVydmVudGlvbiwKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGN5dG9fY29uY19wZ19tbCkgJT4lCiAgbXV0YXRlKHllbGxvd19GQyA9IHBvc3RfWWVsbG93L3ByZV9ZZWxsb3csCiAgICAgICAgIHJlZF9GQyA9IHBvc3RfUmVkL3ByZV9SZWQsCiAgICAgICAgIHBvc3RfaW50ZXJ2ZW50aW9uX0ZDID0gcG9zdF9SZWQvcG9zdF9ZZWxsb3cpCgpyZWRfc2lnY3l0b2tpbmVzX3N1YnNldCAlPiUKICBzdW1tYXJpemUobWVhbl95ZWxsb3dfRkMgPSBtZWFuKHllbGxvd19GQywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbWVhbl9yZWRfRkMgPSBtZWFuKHJlZF9GQyksCiAgICAgICAgICAgIG1lYW5faW50ZXJ2ZW50aW9uX0ZDID0gbWVhbihwb3N0X2ludGVydmVudGlvbl9GQywgbmEucm0gPSBUUlVFKSkKCmBgYAoKIyMjIEludGVydmVudGlvbiBjb21wYXJpc29uCmBgYHtyfQood2lsY294X2N5dG9faW50ZXJ2ZW50aW9uIDwtIGN5dG9raW5lc19ub091dGxpZXJfbG9uZyAlPiUKICBmaWx0ZXIocGF0aWVudF9pZCAhPSA2MTEyKSAlPiUgIyByZW1vdmUgc3ViamVjdCA2MTEyIHNvIHRoZSByZWQgdnMgeWVsbG93IGNvbXBhcmlzb24gaXMgZXZlbgogIGZpbHRlcihwcmVfcG9zdCA9PSAicG9zdCIpICU+JQogIGdyb3VwX2J5KGN5dG9raW5lKSAlPiUKICB3aWxjb3hfdGVzdChjeXRvX2NvbmNfcGdfbWwgfiBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIGRldGFpbGVkID0gVFJVRSkpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCihzaWdfY3l0b2tpbmVzX2ludGVydmVudGlvbiA8LSB3aWxjb3hfY3l0b19pbnRlcnZlbnRpb24gJT4lCiAgZmlsdGVyKHAgPCAwLjA1KSkKCmBgYAoKCiMgSW1tdW5lIENlbGxzCgpgYGB7cn0KIyBjb252ZXJ0IGltbXVuZSBjZWxsIGRhdGEgZnJvbSB3aWRlIHRvIGxvbmcKY2VsbHNfbG9uZyA8LSBpbXB1dGVkX21ldGFfdGFibGUgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgieCIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJjZWxsX3R5cGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY2VsbF92YWx1ZSIpCmBgYAoKCkxldCdzIHJlbW92ZSBzdWJqZWN0IGRhdGEgcG9pbnRzIGZvciBzdWJqZWN0IDYxMTIncyB5ZWxsb3cgaW50ZXJ2ZW50aW9uIGZpcnN0ICh0aGVpciB0b3RhbCBseWNvcGVuZSBsZXZlbHMgaW5jcmVhc2VkIHBvc3QteWVsbG93IGludGVydmVudGlvbikKCmBgYHtyfQpjZWxsc19ub091dGxpZXJfbG9uZyA8LSBhbnRpX2pvaW4oY2VsbHNfbG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ymo2MTEyX3llbGxvdykKYGBgCgoKQWZ0ZXIgdGVzdGluZyBzZXZlcmFsIG1peGVkIGxpbmVhciBtb2RlbHMsIHRoZSBiZXN0IG1vZGVsIHR1cm5lZCBvdXQgdG8gaGF2ZSBwcmVfcG9zdCBhcyBhIGZpeGVkIHZhcmlhYmxlIGFuZCBwYXRpZW50X2lkIGFzIHJhbmRvbSBlZmZlY3QuIENhcm90ZW5vaWRzIGFkZGVkIG5vIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZWZmZWN0IHRvIHRoZSBtb2RlbCwgc3VnZ2VzdGluZyB0aGF0IGNhcm90ZW5vaWRzIGFyZSBub3QgY29udHJpYnV0aW5nIHRvIGN5dG9raW5lIGxldmVscy4gV2UgZGVjaWRlZCB0byBtb3ZlIG9uIHdpdGggcGFpcmVkIG1lYW4gY29tcGFyaXNvbnMgZm9yIGVhY2ggZ3JvdXAuIE1heSByZXZpc2l0IG1peGVkIGxpbmVhciBtb2RlbGluZyB0byBzZWUgaWYgc2lnbmlmaWNhbnQgbWV0YWJvbGl0ZXMgZnJvbSBtZXRhYm9sb21pY3MgYW5hbHlzZXMgYWZmZWN0IGltbXVuZSBvdXRjb21lcyAoaS5lLiBjeXRva2luZSBjb25jZW50cmF0aW9ucyBhbmQgaW1tdW5lIGNlbGwgcG9wdWxhdGlvbnMpLgoKIyMgTm9ybWFsaXR5IGNoZWNrCgpgYGB7cn0KY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICBzaGFwaXJvX3Rlc3QoY2VsbF92YWx1ZSkKYGBgCgpEYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCBmb3Igc2V2ZXJhbCBjZWxsIHR5cGVzLCBzbyBpdCB3aWxsIGJlIG1vcmUgYXBwcm9wcmlhdGUgdXNlIG5vbnBhcmFtZXRyaWMgcGFpcmVkIHRlc3RzIGZvciB0aGUgbWVhbiBjb21wYXJpc29ucy4KCgoKCiMjIFdpbGNveG9uIHJhbmstc3VtIHRlc3RzCgojIyMgQ2FycnlvdmVyIGVmZmVjdHM/CgpGaXJzdCwgbGV0J3MgdGVzdCBmb3Igc2VxdWVuY2UgZWZmZWN0cy4gV2UgZG9uJ3QgZXhwZWN0IHRvIGhhdmUgdGhpcyBwcm9ibGVtIHNpbmNlIHRoZSBwYXJ0aWNpcGFudHMgZGlkIGEgNC13ZWVrIHdhc2hvdXQgcGVyaW9kIChubyB0b21hdG8vbHljb3BlbmUgb3Igc295IGlzb2ZsYXZvbmUtY29udGFpbmluZyBmb29kcykuIFRoaXMgc2hvdWxkIGhhdmUgYmVlbiBzdWZmaWNpZW50IGVub3VnaCBmb3IgdGhlIGludGVydmVudGlvbiB0byBub3QgaGF2ZSBsaW5nZXJpbmcgZWZmZWN0cyBvbiBjZWxsIHBvcHVsYXRpb25zLgoKCgpgYGB7cn0Kd2lsY294X2NlbGxzX3NlcWVmZmVjdHMgPC0gY2VsbHNfbG9uZyAlPiUKICAgZmlsdGVyKHByZV9wb3N0ID09ICJwb3N0IikgJT4lCiAgIGdyb3VwX2J5KGNlbGxfdHlwZSkgJT4lCiAgIHdpbGNveF90ZXN0KGNlbGxfdmFsdWUgfiBzZXF1ZW5jZSwgcGFpcmVkID0gVFJVRSwgcC5hZGp1c3QubWV0aG9kID0gIkJIIiwgZGV0YWlsZWQgPSBUUlVFKQoKa2FibGUod2lsY294X2NlbGxzX3NlcWVmZmVjdHMsIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCndpbGNveF9jZWxsc19zZXFlZmZlY3RzICU+JQogIGZpbHRlcihwIDwgMC4wNSkKYGBgCgpTZWVtcyB0byBiZSBzZXF1ZW5jZSBlZmZlY3RzIGZvciBjZWxsIHR5cGUgIzE5LiBXZSB3aWxsIGtlZXAgdGhpcyBpbiBtaW5kIGZvciB0aGUgcmVzdCBvZiB0aGUgYW5hbHlzZXMuCgojIyMgWWVsbG93IHRydCBlZmZlY3RzCgpDb21wYXJpbmcgcHJlLSB0byBwb3N0LXllbGxvdyAobG93IGNhcm90ZW5vaWQpIGludGVydmVudGlvbgoKYGBge3J9CndpbGNveF9jZWxsc195ZWxsb3cgPC0gY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiWWVsbG93IikgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICB3aWxjb3hfdGVzdChjZWxsX3ZhbHVlIH4gcHJlX3Bvc3QsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIGRldGFpbGVkID0gVFJVRSkKCmthYmxlKHdpbGNveF9jZWxsc195ZWxsb3csIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCihzaWdfY2VsbHNfeWVsbG93IDwtIHdpbGNveF9jZWxsc195ZWxsb3cgJT4lCiAgZmlsdGVyKHAgPCAwLjA1KSkKYGBgCgojIyMjIFNpZyBjZWxscwoKIyMjIyMgYm94cGxvdHMKCmBgYHtyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoPSAxMn0KKHNpZ2NlbGxzX3llbGxvd19icCA8LSBjZWxsc19ub091dGxpZXJfbG9uZyAlPiUgCiAgZmlsdGVyKGNlbGxfdHlwZSAlaW4lIHNpZ19jZWxsc195ZWxsb3ckY2VsbF90eXBlKSAlPiUKICBmaWx0ZXIoaW50ZXJ2ZW50aW9uID09ICJZZWxsb3ciKSAlPiUKICBnZ3BhaXJlZCh4ID0gInByZV9wb3N0IiwgeSA9ICJjZWxsX3ZhbHVlIiwgZmlsbCA9ICJpbnRlcnZlbnRpb24iLCBmYWNldC5ieSA9IGMoImNlbGxfdHlwZSIpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiWWVsbG93IiA9ICJ5ZWxsb3cxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjE1KSArCiAgdGhlbWVfY2xlYW4oYmFzZV9zaXplID0gMTgsIGJhc2VfZmFtaWx5ID0gInNhbnMiKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIkNlbGwgcGVyY2VudGFnZSIsCiAgICAgICB0aXRsZSA9ICJDZWxsIHBvcHVsYXRpb25zIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGJldHdlZW4gcHJlLSBhbmQgcG9zdC1ZZWxsb3ciLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiKSkKCmBgYAoKTG9nMiB0aGUgc2NhbGUgc28gY2hhbmdlIGlzIG1vcmUgdmlzaWJsZQpgYGB7ciwgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aD0gMTJ9CmNlbGxzX25vT3V0bGllcl9sb25nICU+JSAKICBmaWx0ZXIoY2VsbF90eXBlICVpbiUgc2lnX2NlbGxzX3llbGxvdyRjZWxsX3R5cGUpICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlllbGxvdyIpICU+JQogICBtdXRhdGUobG9nMl9jZWxsdmFsdWUgPSBsb2cyKGNlbGxfdmFsdWUpKSAlPiUKICBnZ3BhaXJlZCh4ID0gInByZV9wb3N0IiwgeSA9ICJsb2cyX2NlbGx2YWx1ZSIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgZmFjZXQuYnkgPSBjKCJjZWxsX3R5cGUiKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlllbGxvdyIgPSAieWVsbG93MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkIiA9ICJ0b21hdG8xIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW50ZXJ2ZW50aW9uIikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBwYXRpZW50X2lkKSwgY29sb3VyID0gImdyYXkiLCBzaXplID0gMC4xNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJMb2cyIGNlbGwgJSIsCiAgICAgICB0aXRsZSA9ICJDZWxsIHBvcHVsYXRpb25zIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGJldHdlZW4gcHJlLSBhbmQgcG9zdC1ZZWxsb3ciLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiKQoKYGBgCgpMZXQncyBzZWUgd2hhdCB0aGluZ3MgbG9vayBsaWtlIGluIHJlZCBpbnRlcnZlbnRpb24KYGBge3IsIGZpZy5oZWlnaHQgPSAxMiwgZmlnLndpZHRoPSAxMn0KY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lIAogIGZpbHRlcihjZWxsX3R5cGUgJWluJSBzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZSkgJT4lCiAgbXV0YXRlKGxvZzJfY2VsbHZhbHVlID0gbG9nMihjZWxsX3ZhbHVlKSkgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiUmVkIikgJT4lCiAgZ2dwYWlyZWQoeCA9ICJwcmVfcG9zdCIsIHkgPSAibG9nMl9jZWxsdmFsdWUiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gYygiY2VsbF90eXBlIikpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJZZWxsb3ciID0gInllbGxvdzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZCIgPSAidG9tYXRvMSIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlRvbWF0byBTb3kiKSwKICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkludGVydmVudGlvbiIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gcGF0aWVudF9pZCksIGNvbG91ciA9ICJncmF5Iiwgc2l6ZSA9IDAuMTUpICsKICB0aGVtZV9jbGVhbihiYXNlX3NpemUgPSAxOCwgYmFzZV9mYW1pbHkgPSAic2FucyIpICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAiTG9nMiBjZWxsICUiLAogICAgICAgdGl0bGUgPSAiQ2VsbCBwb3B1bGF0aW9ucyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBiZXR3ZWVuIHByZS0gYW5kIHBvc3QtWWVsbG93IiwKICAgICAgIHN1YnRpdGxlID0gIiIpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgcC5hZGp1c3QubWV0aG9kID0gIkJIIikKCmBgYAoKQ2VsbCAjMjYgKE5haXZlIEItY2VsbCkgaXMgc2lnbmlmaWNhbnRseSBpbmNyZWFzZWQgYWZ0ZXIgYm90aCBpbnRlcnZlbnRpb25zLCBhbHRob3VnaCBwb3N0LXJlZCBoYXMgYSBzdHJvbmdlciBzaWduaWZpY2FuY2UuCgojIyMjIyBsaW5lcGxvdHMKVG8gZ2V0IGEgc2Vuc2Ugb2YgY2VsbCBwb3B1bGF0aW9uIHBlcmNlbnRhZ2VzIG9uIHRoZSBpbmRpdmlkdWFsIGJhc2lzLCB3ZSdsbCBsb29rIGF0IGxpbmUgZ3JhcGhzLgoKSSdtIGdvaW5nIHRvIG1ha2UgYSBmdW5jdGlvbiBmb3IgdGhpcyBmb3IgdGhpcyBmaXJzdC4KCmBgYHtyfQojIGZ1bmN0aW9uIGZvciBsaW5lIHBsb3RzCmxpbmVfcGxvdHNfY2VsbHNfZnggPC0gZnVuY3Rpb24oaW1tdW5lX2NlbGwpIHsKICBjZWxsc19sb25nICU+JSAjIGV2ZW4gdGhvdWdoIHRoaXMgc3ViamVjdCA2MTEyIHdhc250IGluY2x1ZGVkIGZvciB5ZWxsb3cgc3RhdHMsIEknbGwgc3RpbGwgaW5jbHVkZSB0aGVtIGZvciB0aGUgcGxvdHMKICAgIGZpbHRlcihjZWxsX3R5cGUgPT0gaW1tdW5lX2NlbGwpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gcHJlX3Bvc3QsIHkgPSBjZWxsX3ZhbHVlLCBjb2xvciA9IGludGVydmVudGlvbikpICsKICAgIGdlb21fbGluZShhZXMoZ3JvdXAgPSBpbnRlcnZlbnRpb24pKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiWWVsbG93IiA9ICJnb2xkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkIiA9ICJ0b21hdG8xIikpICsKICAgIGZhY2V0X3dyYXAodmFycyhwYXRpZW50X2lkKSwgc2NhbGVzID0gImZyZWVfeSIpICsgCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgbGFicyh4ID0gIiIsCiAgICAgICAgIHkgPSAiQ2VsbCBwb3B1bGF0aW9uICglKSIsCiAgICAgICAgIHRpdGxlID0gcGFzdGUoaW1tdW5lX2NlbGwsICJpbiBlYWNoIHBhdGllbnQgcHJlLSBhbmQgcG9zdC0gcmVkIGFuZCB5ZWxsb3cgaW50ZXJ2ZW50aW9uIikpCn0KYGBgCgpgYGB7cn0KIyBjcmVhdGUgbGlzdCBmb3IgcGxvdHMKbGluZXBsb3RzX2NlbGxzIDwtIGxpc3QoKQoKIyBydW4gdGhpcyBmdW5jdGlvbiBvbiBhbGwgY2VsbCB0eXBlcwpmb3IgKGkgaW4gY2VsbHNfbm9PdXRsaWVyX2xvbmckY2VsbF90eXBlKSB7CiAgbGluZXBsb3RzX2NlbGxzW1tpXV0gPSBsaW5lX3Bsb3RzX2NlbGxzX2Z4KGkpCn0KCmBgYAoKYGBge3J9CiMgc2lnbmlmIGltbXVuZSBjZWxscyBwcmUgdnMgcG9zdCB5ZWxsb3cKc2lnX2NlbGxzX3llbGxvdyRjZWxsX3R5cGUKYGBgCgoKIyMjIyMjIDUtIENENC1DRDgrIChDRDggVCBjZWxscykKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZVsxXV0KYGBgCgojIyMjIyMgOC0gQ0Q0NVJPK0NENDVSQS0gKEVNIENEOCkKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZVsyXV0KYGBgCgojIyMjIyMgOS0gQ0Q0NVJPLUNENDVSQSsgKFRFIENENCkKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZVszXV0KYGBgCgojIyMjIyMgMTUtIENENDVSTy1DRDQ1UkErIChURSBDRDQpCgpgYGB7cn0KbGluZXBsb3RzX2NlbGxzW3NpZ19jZWxsc195ZWxsb3ckY2VsbF90eXBlWzRdXQpgYGAKCiMjIyMjIyAyNi0gQ0QyNy1JZ0QrIChOYWl2ZSBCIGNlbGxzKQpgYGB7cn0KbGluZXBsb3RzX2NlbGxzW3NpZ19jZWxsc195ZWxsb3ckY2VsbF90eXBlWzVdXQpgYGAKCiMjIyMjIyAzNy0gQ0Q1NitDRDE2MStDRDEyMy0gKE5LIGNlbGxzKQoKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZVs2XV0KYGBgCgoKIyMjIyBmb2xkIGNoYW5nZQoKTGV0J3MgbG9vayBhdCB0aGUgYXZlcmFnZSBmb2xkIGNoYW5nZSBmb3Igc2lnbmlmaWNhbnRseSBjaGFuZ2luZyBjZWxscyBpbiB5ZWxsb3cuIFdlJ2xsIGxvb2sgYXQgdGhlIGF2ZyBmb2xkIGNoYW5nZSBjb21wYXJpbmcgcHJlIHRvIHBvc3QgeWVsbG93LCBwcmUgdG8gcG9zdCBSZWQsIGFuZCBwb3N0LWludGVydmVudGlvbiBjb21wYXJpc29uLgoKYGBge3J9Cgp5ZWxsb3dfc2lnY2VsbHNfc3Vic2V0IDwtIGNlbGxzX25vT3V0bGllcl9sb25nICU+JQogIGZpbHRlcihjZWxsX3R5cGUgJWluJSBzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZSklPiUKICBzZWxlY3QocGF0aWVudF9pZCwgcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCBjZWxsX3R5cGUsIGNlbGxfdmFsdWUpICU+JQogIGdyb3VwX2J5KGNlbGxfdHlwZSkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByZV9wb3N0X2ludGVydmVudGlvbiwKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGNlbGxfdmFsdWUpICU+JQogIG11dGF0ZSh5ZWxsb3dfRkMgPSBwb3N0X1llbGxvdy9wcmVfWWVsbG93LAogICAgICAgICByZWRfRkMgPSBwb3N0X1JlZC9wcmVfUmVkLAogICAgICAgICBwb3N0X2ludGVydmVudGlvbl9GQyA9IHBvc3RfUmVkL3Bvc3RfWWVsbG93KQoKeWVsbG93X3NpZ2NlbGxzX3N1YnNldCAlPiUKICBzdW1tYXJpemUobWVhbl95ZWxsb3dfRkMgPSBtZWFuKHllbGxvd19GQywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbWVhbl9yZWRfRkMgPSBtZWFuKHJlZF9GQyksCiAgICAgICAgICAgIG1lYW5faW50ZXJ2ZW50aW9uX0ZDID0gbWVhbihwb3N0X2ludGVydmVudGlvbl9GQywgbmEucm0gPSBUUlVFKSkKCiMgdGhlIGZvbGQgY2hhbmdlIGZvciBjZWxsIHR5cGUgIzE1IHdhcyBodWdlIGZvciByZWQgRkMhIHN1YmplY3QgNjEwOCBoYWQgYSB2ZXJ5IGxhcmdlIGluY3JlYXNlIHBvc3QtcmVkLCBzbyBsZXQncyBzZWUgd2hhdCB0aGUgZm9sZCBjaGFuZ2UgaXMgbGlrZSB3aXRob3V0IHRoYXQgc3ViamVjdAp5ZWxsb3dfc2lnY2VsbHNfc3Vic2V0ICU+JQogIGZpbHRlcihwYXRpZW50X2lkICE9IDYxMDgpICU+JQogIHN1bW1hcml6ZShtZWFuX3llbGxvd19GQyA9IG1lYW4oeWVsbG93X0ZDLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtZWFuX3JlZF9GQyA9IG1lYW4ocmVkX0ZDKSwKICAgICAgICAgICAgbWVhbl9pbnRlcnZlbnRpb25fRkMgPSBtZWFuKHBvc3RfaW50ZXJ2ZW50aW9uX0ZDLCBuYS5ybSA9IFRSVUUpKQoKYGBgCgojIyMgUmVkIHRydCBlZmZlY3RzCgpDb21wYXJpbmcgcHJlLSB0byBwb3N0LXllbGxvdyAobG93IGNhcm90ZW5vaWQpIGludGVydmVudGlvbgoKYGBge3J9CndpbGNveF9jZWxsc19yZWQgPC0gY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiUmVkIikgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICB3aWxjb3hfdGVzdChjZWxsX3ZhbHVlIH4gcHJlX3Bvc3QsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIGRldGFpbGVkID0gVFJVRSkKCmthYmxlKHdpbGNveF9jZWxsc19yZWQsIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCihzaWdfY2VsbHNfcmVkIDwtIHdpbGNveF9jZWxsc19yZWQgJT4lCiAgZmlsdGVyKHAgPCAwLjA1KSkKYGBgCgojIyMjIFNpZyBjZWxscwoKIyMjIyMgYm94cGxvdHMKYGBge3IsIGZpZy53aWR0aD0gMTJ9CmNlbGxzX25vT3V0bGllcl9sb25nICU+JSAKICBmaWx0ZXIoY2VsbF90eXBlICVpbiUgc2lnX2NlbGxzX3JlZCRjZWxsX3R5cGUpICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlJlZCIpICU+JQogIGdncGFpcmVkKHggPSAicHJlX3Bvc3QiLCB5ID0gImNlbGxfdmFsdWUiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gImNlbGxfdHlwZSIsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgcGFuZWwubGFicyA9IGxpc3QoY2VsbF90eXBlID0gYygiQ0Q0NVJPKyBDRDQ1UkEtIChFTSBDRDgpIiwiQ0QxOStDRDMtIChCIGNlbGxzKSIsICJDRDI3LUlnRCsgKE5haXZlIEIgY2VsbHMpIikpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiWWVsbG93IiA9ICJ5ZWxsb3cxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJUb21hdG8tc295IiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjE1KSArCiAgdGhlbWVfY2xlYW4oYmFzZV9zaXplID0gMTgsIGJhc2VfZmFtaWx5ID0gInNhbnMiKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIkNlbGwgdmFsdWUiLAogICAgICAgdGl0bGUgPSAiQ2VsbCBwb3B1bGF0aW9ucyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBiZXR3ZWVuIHByZS0gYW5kIHBvc3QtVG9tYXRvIHNveSIsCiAgICAgICBzdWJ0aXRsZSA9ICIiKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIpCgpgYGAKCkxldCdzIHNlZSB3aGF0IHRoaXMgbG9va3MgbGlrZSBwcmUtIGFuZCBwb3N0LSBjb250cm9sCgpgYGB7ciwgZmlnLndpZHRoPSAxMn0KY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lIAogIGZpbHRlcihjZWxsX3R5cGUgJWluJSBzaWdfY2VsbHNfcmVkJGNlbGxfdHlwZSkgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiWWVsbG93IikgJT4lCiAgZ2dwYWlyZWQoeCA9ICJwcmVfcG9zdCIsIHkgPSAiY2VsbF92YWx1ZSIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgZmFjZXQuYnkgPSAiY2VsbF90eXBlIiwgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBwYW5lbC5sYWJzID0gbGlzdChjZWxsX3R5cGUgPSBjKCJDRDQ1Uk8rIENENDVSQS0gKEVNIENEOCkiLCJDRDE5K0NEMy0gKEIgY2VsbHMpIiwgIkNEMjctSWdEKyAoTmFpdmUgQiBjZWxscykiKSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJZZWxsb3ciID0gInllbGxvdzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZCIgPSAidG9tYXRvMSIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiKSwKICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkludGVydmVudGlvbiIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gcGF0aWVudF9pZCksIGNvbG91ciA9ICJncmF5Iiwgc2l6ZSA9IDAuMTUpICsKICB0aGVtZV9jbGVhbihiYXNlX3NpemUgPSAxOCwgYmFzZV9mYW1pbHkgPSAic2FucyIpICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAiQ2VsbCB2YWx1ZSIsCiAgICAgICB0aXRsZSA9ICJDZWxsIHBvcHVsYXRpb25zIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGJldHdlZW4gcHJlLSBhbmQgcG9zdC1Ub21hdG8gc295IiwKICAgICAgIHN1YnRpdGxlID0gIiIpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgcC5hZGp1c3QubWV0aG9kID0gIkJIIikKCmBgYAoKRU0gQ0Q4IGFuZCBOYWl2ZSBCLSBjZWxscyBhcmUgc2lnbmlmaWNhbnRseSBpbmNyZWFzZWQgcG9zdCBjb250cm9sIGFzIHdlbGwuIFN0cm9uZ2VyIGVmZmVjdCBpbiBjb250cm9sLgoKIyMjIyMgbGluZXBsb3RzClRvIGdldCBhIHNlbnNlIG9mIGNlbGwgcG9wdWxhdGlvbiBwZXJjZW50YWdlcyBvbiB0aGUgaW5kaXZpZHVhbCBiYXNpcywgd2UnbGwgbG9vayBhdCBsaW5lIGdyYXBocy4KCiMjIyMjIyA4LSBDRDQ1Uk8rQ0Q0NVJBLSAoRU0gQ0Q4KQpgYGB7cn0KbGluZXBsb3RzX2NlbGxzW3NpZ19jZWxsc19yZWQkY2VsbF90eXBlWzFdXQpgYGAKCgojIyMjIyMgMjUtIENEMTkrQ0QzLSAoQiBjZWxscykKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfcmVkJGNlbGxfdHlwZVsyXV0KYGBgCgoKIyMjIyMjIDI2LSBDRDI3LUlnRCsgKE5haXZlIEIgY2VsbHMpCmBgYHtyfQpsaW5lcGxvdHNfY2VsbHNbc2lnX2NlbGxzX3JlZCRjZWxsX3R5cGVbM11dCmBgYAoKCiMjIyMgZm9sZCBjaGFuZ2UKCkxldCdzIGxvb2sgYXQgdGhlIGF2ZXJhZ2UgZm9sZCBjaGFuZ2UgZm9yIHNpZ25pZmljYW50bHkgY2hhbmdpbmcgY2VsbHMgaW4gcmVkLiBXZSdsbCBsb29rIGF0IHRoZSBhdmcgZm9sZCBjaGFuZ2UgY29tcGFyaW5nIHByZSB0byBwb3N0IHllbGxvdywgcHJlIHRvIHBvc3QgUmVkLCBhbmQgcG9zdC1pbnRlcnZlbnRpb24gY29tcGFyaXNvbi4KCmBgYHtyfQoKcmVkX3NpZ2NlbGxzX3N1YnNldCA8LSBjZWxsc19ub091dGxpZXJfbG9uZyAlPiUKICBmaWx0ZXIoY2VsbF90eXBlICVpbiUgc2lnX2NlbGxzX3JlZCRjZWxsX3R5cGUpJT4lCiAgc2VsZWN0KHBhdGllbnRfaWQsIHByZV9wb3N0X2ludGVydmVudGlvbiwgY2VsbF90eXBlLCBjZWxsX3ZhbHVlKSAlPiUKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBwcmVfcG9zdF9pbnRlcnZlbnRpb24sCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjZWxsX3ZhbHVlKSAlPiUKICBtdXRhdGUoeWVsbG93X0ZDID0gcG9zdF9ZZWxsb3cvcHJlX1llbGxvdywKICAgICAgICAgcmVkX0ZDID0gcG9zdF9SZWQvcHJlX1JlZCwKICAgICAgICAgcG9zdF9pbnRlcnZlbnRpb25fRkMgPSBwb3N0X1JlZC9wb3N0X1llbGxvdykKCnJlZF9zaWdjZWxsc19zdWJzZXQgJT4lCiAgc3VtbWFyaXplKG1lYW5feWVsbG93X0ZDID0gbWVhbih5ZWxsb3dfRkMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1lYW5fcmVkX0ZDID0gbWVhbihyZWRfRkMpLAogICAgICAgICAgICBtZWFuX2ludGVydmVudGlvbl9GQyA9IG1lYW4ocG9zdF9pbnRlcnZlbnRpb25fRkMsIG5hLnJtID0gVFJVRSkpCgpgYGAKCiMjIyBQb3N0LXRydCBjb21wYXJpc29uCgpDb21wYXJpbmcgcG9zdC10b21hdG8gc295IHRvIHBvc3QtY29udHJvbCBpbnRlcnZlbnRpb24KCmBgYHtyfQp3aWxjb3hfY2VsbHNfaW50ZXJ2ZW50aW9uIDwtIGNlbGxzX25vT3V0bGllcl9sb25nICU+JQogIGZpbHRlcihwcmVfcG9zdCA9PSAicG9zdCIsCiAgICAgICAgIHBhdGllbnRfaWQgIT0gIjYxMTIiKSAlPiUKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIHdpbGNveF90ZXN0KGNlbGxfdmFsdWUgfiBpbnRlcnZlbnRpb24sIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIGRldGFpbGVkID0gVFJVRSkKCmthYmxlKHdpbGNveF9jZWxsc19pbnRlcnZlbnRpb24sIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKCmBgYHtyfQojIGV4dHJhY3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBjeXRva2luZXMgCihzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uIDwtIHdpbGNveF9jZWxsc19pbnRlcnZlbnRpb24gJT4lCiAgZmlsdGVyKHAgPCAwLjA1KSkKYGBgCgojIyMjIFNpZyBjZWxscwoKIyMjIyMgYm94cGxvdHMKYGBge3IsIGZpZy53aWR0aD0xMH0KY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lIAogIGZpbHRlcihjZWxsX3R5cGUgJWluJSBzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uJGNlbGxfdHlwZSkgJT4lCiAgZmlsdGVyKHByZV9wb3N0ID09ICJwb3N0IikgJT4lCiAgZ2dwYWlyZWQoeCA9ICJwcmVfcG9zdF9pbnRlcnZlbnRpb24iLCB5ID0gImNlbGxfdmFsdWUiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gImNlbGxfdHlwZSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJZZWxsb3ciID0gInllbGxvdzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZCIgPSAidG9tYXRvMSIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiVG9tYXRvLXNveSIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW50ZXJ2ZW50aW9uIikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBwYXRpZW50X2lkKSwgY29sb3VyID0gImdyYXkiLCBzaXplID0gMC4yNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJDZWxsIHZhbHVlIiwKICAgICAgIHRpdGxlID0gIkNlbGwgcG9wdWxhdGlvbnMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBwb3N0LUNvbnRyb2wgYW5kIHBvc3QtVG9tYXRvIHNveSBqdWljZXMiLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiLCBjb21wYXJpc29ucyA9IGxpc3QoYygicG9zdF9ZZWxsb3ciLCAicG9zdF9SZWQiKSksIGxhYmVsLnkgPSA0MCkKCmBgYAoKTGV0J3MgbG9vayBhdCB0aGUgdHJlbmRzIGZvciB0aGVzZSBjZWxsIHR5cGVzIGR1cmluZyBpbmRpdmlkdWFsIGludGVydmVudGlvbnMKYGBge3J9CmNlbGxzX25vT3V0bGllcl9sb25nICU+JSAKICBmaWx0ZXIoY2VsbF90eXBlICVpbiUgc2lnX2NlbGxzX2ludGVydmVudGlvbiRjZWxsX3R5cGUpICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlJlZCIpICU+JQogIGdncGFpcmVkKHggPSAicHJlX3Bvc3QiLCB5ID0gImNlbGxfdmFsdWUiLCBmaWxsID0gImludGVydmVudGlvbiIsIGZhY2V0LmJ5ID0gImNlbGxfdHlwZSIsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgcGFuZWwubGFicyA9IGxpc3QoY2VsbF90eXBlID0gYygiQ0QxNi0gTksgY2VsbHMiLCJDRDE0KyBNRFNDIChNb25vKSIpKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlllbGxvdyIgPSAieWVsbG93MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkIiA9ICJ0b21hdG8xIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiVG9tYXRvLXNveSIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiSW50ZXJ2ZW50aW9uIikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBwYXRpZW50X2lkKSwgY29sb3VyID0gImdyYXkiLCBzaXplID0gMC4yNSkgKwogIHRoZW1lX2NsZWFuKGJhc2Vfc2l6ZSA9IDE4LCBiYXNlX2ZhbWlseSA9ICJzYW5zIikgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICJDZWxsIHZhbHVlIiwKICAgICAgIHRpdGxlID0gIkNlbGwgcG9wdWxhdGlvbnMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBwb3N0LUNvbnRyb2wgYW5kIHBvc3QtVG9tYXRvIHNveSBqdWljZXMiLAogICAgICAgc3VidGl0bGUgPSAiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBwLmFkanVzdC5tZXRob2QgPSAiQkgiKQoKYGBgCgoKYGBge3IsZmlnLndpZHRoPSAxMn0KY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lIAogIGZpbHRlcihjZWxsX3R5cGUgJWluJSBzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uJGNlbGxfdHlwZSkgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiWWVsbG93IikgJT4lCiAgZ2dwYWlyZWQoeCA9ICJwcmVfcG9zdCIsIHkgPSAiY2VsbF92YWx1ZSIsIGZpbGwgPSAiaW50ZXJ2ZW50aW9uIiwgZmFjZXQuYnkgPSAiY2VsbF90eXBlIiwgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBwYW5lbC5sYWJzID0gbGlzdChjZWxsX3R5cGUgPSBjKCJDRDE2LSBOSyBjZWxscyIsIkNEMTQrIE1EU0MgKE1vbm8pIikpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiWWVsbG93IiA9ICJ5ZWxsb3cxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQiID0gInRvbWF0bzEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJJbnRlcnZlbnRpb24iKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpLCBjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjI1KSArCiAgdGhlbWVfY2xlYW4oYmFzZV9zaXplID0gMTgsIGJhc2VfZmFtaWx5ID0gInNhbnMiKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIkNlbGwgdmFsdWUiLAogICAgICAgdGl0bGUgPSAiQ2VsbCBwb3B1bGF0aW9ucyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBiZXR3ZWVuIHBvc3QtQ29udHJvbCBhbmQgcG9zdC1Ub21hdG8gc295IGp1aWNlcyIsCiAgICAgICBzdWJ0aXRsZSA9ICIiKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIpCgpgYGAKCiMjIyMjIGxpbmVwbG90cwpUbyBnZXQgYSBzZW5zZSBvZiBjZWxsIHBvcHVsYXRpb24gcGVyY2VudGFnZXMgb24gdGhlIGluZGl2aWR1YWwgYmFzaXMsIHdlJ2xsIGxvb2sgYXQgbGluZSBncmFwaHMuCgojIyMjIyMgMzgtIENEMTYtIE5LIGNlbGxzCgoKYGBge3J9CmxpbmVwbG90c19jZWxsc1tzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uJGNlbGxfdHlwZVsxXV0KYGBgCgpMb29raW5nIGF0IHBvc3QgY29udHJvbCB2IHBvc3QgdG9tYXRvIHNveQoKYGBge3J9CmltcHV0ZWRfbWV0YV90YWJsZSAlPiUgCiAgZmlsdGVyKHByZV9wb3N0ID09ICJwb3N0IikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCB5ID0geDM4X2NkMTZfbmtfY2VsbHMsIGNvbG9yID0gcGF0aWVudF9pZCkpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gcGF0aWVudF9pZCkpICsKICB0aGVtZV9idygpICsKICBsYWJzKHggPSAiVGltZXBvaW50IiwKICAgICAgIHkgPSAiUG9wdWxhdGlvbiBsZXZlbCAoJSkiLAogICAgICAgdGl0bGUgPSAiQ0QxNi0gTksgQ2VsbCBwb3B1bGF0aW9ucyBpbiBlYWNoIHBhdGllbnQgYmV0d2VlbiBwb3N0LSBpbnRlcnZlbnRpb25zIikKYGBgCgoKIyMjIyMjIDQwLSBDRDE0KyBNRFNDIChNb25vKQpgYGB7cn0KbGluZXBsb3RzX2NlbGxzW3NpZ19jZWxsc19pbnRlcnZlbnRpb24kY2VsbF90eXBlWzJdXQpgYGAKCgpMZXQncyBsb29rIGF0IHBvc3QgY29udHJvbCB2cyBwb3N0IHRvbWF0byBzb3kKYGBge3J9CmltcHV0ZWRfbWV0YV90YWJsZSAlPiUgCiAgZmlsdGVyKHByZV9wb3N0ID09ICJwb3N0IikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCB5ID0geDQwX2NkMTRfbWRzY19tb25vLCBjb2xvciA9IHBhdGllbnRfaWQpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHBhdGllbnRfaWQpKSArCiAgdGhlbWVfYncoKSArCiAgbGFicyh4ID0gIlRpbWVwb2ludCIsCiAgICAgICB5ID0gIlBvcHVsYXRpb24gbGV2ZWwgKCUpIiwKICAgICAgIHRpdGxlID0gIkNEMTQrIG1vbm9jeXRpYyBNRFNDIHBvcHVsYXRpb25zIGluIGVhY2ggcGF0aWVudCBiZXR3ZWVuIHBvc3QtIGludGVydmVudGlvbnMiKQpgYGAKCgojIyMjIGZvbGQgY2hhbmdlCgpMZXQncyBsb29rIGF0IHRoZSBhdmVyYWdlIGZvbGQgY2hhbmdlIGZvciBzaWduaWZpY2FudGx5IGNoYW5naW5nIGNlbGxzIGluIHJlZC4gV2UnbGwgbG9vayBhdCB0aGUgYXZnIGZvbGQgY2hhbmdlIGNvbXBhcmluZyBwcmUgdG8gcG9zdCB5ZWxsb3csIHByZSB0byBwb3N0IFJlZCwgYW5kIHBvc3QtaW50ZXJ2ZW50aW9uIGNvbXBhcmlzb24uCgpgYGB7cn0KCmludGVydmVudGlvbl9zaWdjZWxsc19zdWJzZXQgPC0gY2VsbHNfbm9PdXRsaWVyX2xvbmcgJT4lCiAgZmlsdGVyKGNlbGxfdHlwZSAlaW4lIHNpZ19jZWxsc19pbnRlcnZlbnRpb24kY2VsbF90eXBlKSU+JQogIHNlbGVjdChwYXRpZW50X2lkLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIGNlbGxfdHlwZSwgY2VsbF92YWx1ZSkgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gY2VsbF92YWx1ZSkgJT4lCiAgbXV0YXRlKHllbGxvd19GQyA9IHBvc3RfWWVsbG93L3ByZV9ZZWxsb3csCiAgICAgICAgIHJlZF9GQyA9IHBvc3RfUmVkL3ByZV9SZWQsCiAgICAgICAgIHBvc3RfaW50ZXJ2ZW50aW9uX0ZDID0gcG9zdF9SZWQvcG9zdF9ZZWxsb3cpCgppbnRlcnZlbnRpb25fc2lnY2VsbHNfc3Vic2V0ICU+JQogIHN1bW1hcml6ZShtZWFuX3llbGxvd19GQyA9IG1lYW4oeWVsbG93X0ZDLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtZWFuX3JlZF9GQyA9IG1lYW4ocmVkX0ZDKSwKICAgICAgICAgICAgbWVhbl9pbnRlcnZlbnRpb25fRkMgPSBtZWFuKHBvc3RfaW50ZXJ2ZW50aW9uX0ZDLCBuYS5ybSA9IFRSVUUpKQoKYGBgCgpWZXJ5IGxhcmdlIGZvbGQgY2hhbmdlIG9mIGFwcHJveCA0NCB1bml0cyBoaWdoZXIgcG9zdC1SZWQgdnMuIHBvc3QtWWVsbG93IGZvciBNRFNDIGNlbGwgdHlwZS4gCgoKIyBDb3JyZWxhdGlvbiBhbmFseXNlcwoKTGV0J3MgbG9vayBhdCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBzaWduaWZpY2FudCBpbW11bm8gb3V0Y29tZXMgKGZyb20gZWFjaCBjb21wYXJpc29uKSBhbmQgY2Fyb3Rlbm9pZHMuIEkgYWxzbyBwbGFuIHRvIGNvcnJlbGF0ZSB0aGVzZSB3aXRoIHVyaW5hcnkgc295IGlzb2ZsYXZvbmVzIGFuZCB0aGVpciBtZXRhYm9saXRlcywgYWxvbmcgd2l0aCBvdGhlciBzaWduaWZpY2FudCB1cmluYXJ5IG1ldGFib2xpdGVzLiBJIHdpbGwgcGVyZm9ybSBhIGxvZzIgZm9sZCBjaGFuZ2UgdHJhbnNmb3JtYXRpb24gZm9yIHByZS1wb3N0IGNvbXBhcmlzb24gYW5kIGludGVydmVudGlvbiBjb21wYXJpc29ucy4KCiMjIFllbGxvdwpQcmUgdnMgcG9zdCB5ZWxsb3cKCndyYW5nbGluZwpgYGB7cn0KIyBjcmVhdGUgZGYgd2l0aCBwcmUtaW50ZXJ2ZW50aW9ucyBkYXRhCm1ldGFfdGFibGVfcHJlX3N1YnNldCA8LSBpbXB1dGVkX21ldGFfdGFibGUgJT4lCiAgZmlsdGVyKHByZV9wb3N0ID09ICJwcmUiKSAlPiUKICBtdXRhdGVfYXQoMTE6bmNvbCguKSwgbG9nMikKCiMgY3JlYXRlIGRmIHdpdGggcG9zdC1pbnRlcnZlbnRpb25zIGRhdGEKbWV0YV90YWJsZV9wb3N0X3N1YnNldCA8LSBpbXB1dGVkX21ldGFfdGFibGUgJT4lCiAgZmlsdGVyKHByZV9wb3N0ID09ICJwb3N0IikgJT4lCiAgbXV0YXRlX2F0KDExOm5jb2woLiksIGxvZzIpCgojIHN1YnRyYWN0IHByZSBkZiBmcm9tIHBvc3QgZGYKbWV0YV90YWJsZV9wb3N0X3ByZV9kaWZmZXJlbmNlcyA8LSBtZXRhX3RhYmxlX3Bvc3Rfc3Vic2V0WywxMTpuY29sKGltcHV0ZWRfbWV0YV90YWJsZSldIC0gbWV0YV90YWJsZV9wcmVfc3Vic2V0WywxMTpuY29sKGltcHV0ZWRfbWV0YV90YWJsZSldCgojIGFkZCBtZXRhZGF0YSBiYWNrIGluIGFuZCBvcmdhbml6ZSBzbyB0aGF0IG1ldGFkYXRhIGlzIGF0IGJlZ2lubmluZyBvZiBkZgptZXRhX3RhYmxlX3Bvc3RfcHJlX2RpZmZlcmVuY2VzIDwtIG1ldGFfdGFibGVfcG9zdF9wcmVfZGlmZmVyZW5jZXMgJT4lCiAgbXV0YXRlKHBhdGllbnRfaWQgPSBtZXRhX3RhYmxlX3Bvc3Rfc3Vic2V0JHBhdGllbnRfaWQsCiAgICAgICAgIGludGVydmVudGlvbiA9IG1ldGFfdGFibGVfcG9zdF9zdWJzZXQkaW50ZXJ2ZW50aW9uLAogICAgICAgICBhZ2VfYXRfZW5yb2xsbWVudCA9IG1ldGFfdGFibGVfcG9zdF9zdWJzZXQkYWdlX2F0X2Vucm9sbG1lbnQsCiAgICAgICAgIHNleCA9IG1ldGFfdGFibGVfcG9zdF9zdWJzZXQkc2V4LAogICAgICAgICBibWlfYXRfZW5yb2xsbWVudCA9IG1ldGFfdGFibGVfcG9zdF9zdWJzZXQkYm1pX2F0X2Vucm9sbG1lbnQpICU+JQogIHJlbG9jYXRlKHBhdGllbnRfaWQsIGludGVydmVudGlvbiwgc2V4LCBhZ2VfYXRfZW5yb2xsbWVudCwgYm1pX2F0X2Vucm9sbG1lbnQpCmBgYAoKCkNvcnIgdGFibGUgCgpgYGB7cn0KY29ycmVsYXRpb25feWVsbG93IDwtIG1ldGFfdGFibGVfcG9zdF9wcmVfZGlmZmVyZW5jZXMgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiWWVsbG93IikgJT4lCiAgZmlsdGVyKHBhdGllbnRfaWQgIT0gNjExMikgJT4lICMgcmVtb3ZlIHRoaXMgc3ViaiBzaW5jZSB0aGV5IHdlcmUgYW4gb3V0bGllciBpbiBjb250cm9sIGp1aWNlIGZvciB0b3RhbCBseWMKICBzZWxlY3QodG90YWxfbHljLCBhbGxfb2Yoc2lnX2NlbGxzX3llbGxvdyRjZWxsX3R5cGUpLCBhbGxfb2Yoc2lnX2N5dG9raW5lc195ZWxsb3ckY3l0b2tpbmUpKSAlPiUKICBjb3JyZWxhdGUobWV0aG9kID0gInNwZWFybWFuIikKCmthYmxlKGNvcnJlbGF0aW9uX3llbGxvdywgZm9ybWF0ID0gIm1hcmtkb3duIiwgZGlnaXRzID0gMykKYGBgCgoKYGBge3J9CmNvcnJlbGF0aW9uX3llbGxvdyAlPiUKICByZWFycmFuZ2UoYWJzb2x1dGUgPSBGQUxTRSkgJT4lCiAgc2hhdmUoKSAlPiUKICBycGxvdChzaGFwZSA9IDE5LAogICAgICAgIGNvbG9ycyA9IGMoInJlZCIsICJncmVlbiIpLAogICAgICAgIHByaW50X2NvciA9IFRSVUUpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKYGBgCgoKIyMgUmVkCgpgYGB7cn0KY29ycmVsYXRpb25fcmVkIDwtIG1ldGFfdGFibGVfcG9zdF9wcmVfZGlmZmVyZW5jZXMgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiUmVkIikgJT4lCiAgc2VsZWN0KHRvdGFsX2x5YywgYWxsX29mKHNpZ19jZWxsc19yZWQkY2VsbF90eXBlKSwgYWxsX29mKHNpZ19jeXRva2luZXNfcmVkJGN5dG9raW5lKSkgJT4lCiAgY29ycmVsYXRlKG1ldGhvZCA9ICJzcGVhcm1hbiIpCgprYWJsZShjb3JyZWxhdGlvbl9yZWQsIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKYGBge3J9CmNvcnJlbGF0aW9uX3JlZCAlPiUKICByZWFycmFuZ2UoYWJzb2x1dGUgPSBGQUxTRSkgJT4lCiAgc2hhdmUoKSAlPiUKICBycGxvdChzaGFwZSA9IDE5LAogICAgICAgIGNvbG9ycyA9IGMoInJlZCIsICJncmVlbiIpLAogICAgICAgIHByaW50X2NvciA9IFRSVUUpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKYGBgCgojIyBJbnRlcnZlbnRpb24gY29tcGFyaXNvbgoKd3JhbmdsaW5nCmBgYHtyfQojIGNyZWF0ZSBkZiB3aXRoIHByZS1pbnRlcnZlbnRpb25zIGRhdGEKbWV0YV90YWJsZV9wb3N0WV9zdWJzZXQgPC0gaW1wdXRlZF9tZXRhX3RhYmxlICU+JQogIGZpbHRlcihwcmVfcG9zdF9pbnRlcnZlbnRpb24gPT0gInBvc3RfWWVsbG93IikgJT4lCiAgbXV0YXRlX2F0KDExOm5jb2woLiksIGxvZzIpCgojIGNyZWF0ZSBkZiB3aXRoIHBvc3QtaW50ZXJ2ZW50aW9ucyBkYXRhCm1ldGFfdGFibGVfcG9zdFJfc3Vic2V0IDwtIGltcHV0ZWRfbWV0YV90YWJsZSAlPiUKICBmaWx0ZXIocHJlX3Bvc3RfaW50ZXJ2ZW50aW9uID09ICJwb3N0X1JlZCIpICU+JQogIG11dGF0ZV9hdCgxMTpuY29sKC4pLCBsb2cyKQoKIyBzdWJ0cmFjdCBwcmUgZGYgZnJvbSBwb3N0IGRmCm1ldGFfdGFibGVfaW50ZXJ2ZW50aW9uX2RpZmZlcmVuY2VzIDwtIG1ldGFfdGFibGVfcG9zdFJfc3Vic2V0WywxMTpuY29sKGltcHV0ZWRfbWV0YV90YWJsZSldIC0gbWV0YV90YWJsZV9wb3N0WV9zdWJzZXRbLDExOm5jb2woaW1wdXRlZF9tZXRhX3RhYmxlKV0KCiMgYWRkIG1ldGFkYXRhIGJhY2sgaW4gYW5kIG9yZ2FuaXplIHNvIHRoYXQgbWV0YWRhdGEgaXMgYXQgYmVnaW5uaW5nIG9mIGRmCm1ldGFfdGFibGVfaW50ZXJ2ZW50aW9uX2RpZmZlcmVuY2VzIDwtIG1ldGFfdGFibGVfaW50ZXJ2ZW50aW9uX2RpZmZlcmVuY2VzICU+JQogIG11dGF0ZShwYXRpZW50X2lkID0gbWV0YV90YWJsZV9wb3N0Ul9zdWJzZXQkcGF0aWVudF9pZCwKICAgICAgICAgaW50ZXJ2ZW50aW9uID0gbWV0YV90YWJsZV9wb3N0Ul9zdWJzZXQkaW50ZXJ2ZW50aW9uLAogICAgICAgICBhZ2VfYXRfZW5yb2xsbWVudCA9IG1ldGFfdGFibGVfcG9zdFJfc3Vic2V0JGFnZV9hdF9lbnJvbGxtZW50LAogICAgICAgICBzZXggPSBtZXRhX3RhYmxlX3Bvc3RSX3N1YnNldCRzZXgsCiAgICAgICAgIGJtaV9hdF9lbnJvbGxtZW50ID0gbWV0YV90YWJsZV9wb3N0Ul9zdWJzZXQkYm1pX2F0X2Vucm9sbG1lbnQpICU+JQogIHJlbG9jYXRlKHBhdGllbnRfaWQsIGludGVydmVudGlvbiwgc2V4LCBhZ2VfYXRfZW5yb2xsbWVudCwgYm1pX2F0X2Vucm9sbG1lbnQpCmBgYAoKCmBgYHtyfQpjb3JyZWxhdGlvbl9pbnRlcnZlbnRpb24gPC0gbWV0YV90YWJsZV9pbnRlcnZlbnRpb25fZGlmZmVyZW5jZXMgJT4lCiAgZmlsdGVyKGludGVydmVudGlvbiA9PSAiUmVkIikgJT4lCiAgc2VsZWN0KHRvdGFsX2x5YywgYWxsX29mKHNpZ19jZWxsc19pbnRlcnZlbnRpb24kY2VsbF90eXBlKSwgYWxsX29mKHNpZ19jeXRva2luZXNfaW50ZXJ2ZW50aW9uJGN5dG9raW5lKSkgJT4lCiAgY29ycmVsYXRlKG1ldGhvZCA9ICJzcGVhcm1hbiIpCgprYWJsZShjb3JyZWxhdGlvbl9pbnRlcnZlbnRpb24sIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKYGBge3J9CmNvcnJlbGF0aW9uX2ludGVydmVudGlvbiAlPiUKICByZWFycmFuZ2UoYWJzb2x1dGUgPSBGQUxTRSkgJT4lCiAgc2hhdmUoKSAlPiUKICBycGxvdChzaGFwZSA9IDE5LAogICAgICAgIGNvbG9ycyA9IGMoInJlZCIsICJncmVlbiIpLAogICAgICAgIHByaW50X2NvciA9IFRSVUUpCmBgYAoKCiMjIE92ZXJhbGwgY29ycgpMZXQncyB0YWtlIGFsbCBvZiB0aGUgc2lnbmlmaWNhbnQgb3V0Y29tZXMgYW5kIGV2ZW4gYWRkIGFsbCBvZiB0aGUgbWV0YWRhdGEKCiMjIyBwcmUgdiBwb3N0IGRpZmZlcmVuY2UKCmBgYHtyfQpjb3JyZWxhdGlvbl9hbGxfcHJlX3Bvc3Rfc2lnIDwtIG1ldGFfdGFibGVfcG9zdF9wcmVfZGlmZmVyZW5jZXMgJT4lCiAgc2VsZWN0KDI6NSwgdG90YWxfbHljLCB0b3RhbF9jYXJvdGVub2lkcywgYV9jYXJvdGVuZSwgYl9jYXJvdGVuZSwgbHV0ZWluLCB6ZWF4YW50aGluLCBiX2NyeXB0b3hhbnRoaW4sIGFsbF9vZihzaWdfY2VsbHNfcmVkJGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX3JlZCRjeXRva2luZSksIGFsbF9vZihzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX3llbGxvdyRjeXRva2luZSksIGFsbF9vZihzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uJGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX2ludGVydmVudGlvbiRjeXRva2luZSkpICU+JQogIGNvcnJlbGF0ZShtZXRob2QgPSAic3BlYXJtYW4iKQoKa2FibGUoY29ycmVsYXRpb25fYWxsX3ByZV9wb3N0X3NpZywgZm9ybWF0ID0gIm1hcmtkb3duIiwgZGlnaXRzID0gMykKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwfQpjb3JyZWxhdGlvbl9hbGxfcHJlX3Bvc3Rfc2lnICU+JQogIHJlYXJyYW5nZShhYnNvbHV0ZSA9IEZBTFNFKSAlPiUKICBzaGF2ZSgpICU+JQogIHJwbG90KHNoYXBlID0gMTksIAogICAgICAgIHByaW50X2NvciA9IFRSVUUsCiAgICAgICAgY29sb3JzID0gYygicmVkIiwgImdyZWVuIikpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKYGBgCgojIyMgcG9zdCByZWQgdnMgcG9zdCB5ZWxsb3cgZGlmZmVyZW5jZQpgYGB7cn0KY29ycmVsYXRpb25fYWxsX2ludGVydmVudGlvbl9zaWcgPC0gbWV0YV90YWJsZV9pbnRlcnZlbnRpb25fZGlmZmVyZW5jZXMgJT4lCiAgc2VsZWN0KDI6NSwgdG90YWxfbHljLCB0b3RhbF9jYXJvdGVub2lkcywgYV9jYXJvdGVuZSwgYl9jYXJvdGVuZSwgbHV0ZWluLCB6ZWF4YW50aGluLCBiX2NyeXB0b3hhbnRoaW4sIGFsbF9vZihzaWdfY2VsbHNfcmVkJGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX3JlZCRjeXRva2luZSksIGFsbF9vZihzaWdfY2VsbHNfeWVsbG93JGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX3llbGxvdyRjeXRva2luZSksIGFsbF9vZihzaWdfY2VsbHNfaW50ZXJ2ZW50aW9uJGNlbGxfdHlwZSksIGFsbF9vZihzaWdfY3l0b2tpbmVzX2ludGVydmVudGlvbiRjeXRva2luZSkpICU+JQogIGNvcnJlbGF0ZShtZXRob2QgPSAic3BlYXJtYW4iKQoKa2FibGUoY29ycmVsYXRpb25fYWxsX2ludGVydmVudGlvbl9zaWcsIGZvcm1hdCA9ICJtYXJrZG93biIsIGRpZ2l0cyA9IDMpCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMH0KY29ycmVsYXRpb25fYWxsX2ludGVydmVudGlvbl9zaWcgJT4lCiAgcmVhcnJhbmdlKGFic29sdXRlID0gRkFMU0UpICU+JQogIHNoYXZlKCkgJT4lCiAgcnBsb3Qoc2hhcGUgPSAxOSwgCiAgICAgICAgcHJpbnRfY29yID0gVFJVRSwKICAgICAgICBjb2xvcnMgPSBjKCJyZWQiLCAiZ3JlZW4iKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQpgYGAKCiMgSGVhdG1hcAoKIyMgU2lnbmlmaWNhbnQgY3l0b2tpbmVzCgojIyMgWi1zY29yZSB0cmFuc2Zvcm1lZAoKSGVyZSwgSSBhbSB1c2luZyBteSByYXcgZGF0YSBhbmQgYWxsb3dpbmcgdGhlIHBoZWF0bWFwIHBhY2thZ2UgdG8gcGVyZm9ybSB6LXNjYWxpbmcuCgpaLXNjb3Jpbmcgc3RhbmRhcmRpemVzIHRoZSBkYXRhIGJ5IHRoaXMgY2FsY3VsYXRpb246IChpbmRpdmlkdWFsIHZhbHVlIHdpdGhpbiBvdXRjb21lIC0gbWVhbiBvZiBvdXRjb21lKSAvIChzdGQgZGV2KS4gVGhlIHBoZWF0bWFwIHBhY2thZ2UgZG9lcyB0aGlzIGF1dG9tYXRpY2FsbHkgd2l0aCB0aGUgY2FsbCBzY2FsZSA9ICJyb3ciIG9yICJjb2x1bW4iCmBgYHtyLCBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9OSwgZmlnLmFzcD0xfQoKY3l0b2tpbmVfaGVhdG1hcF9kYXRhIDwtIGltcHV0ZWRfbWV0YV90YWJsZSAlPiUKICB1bml0ZSgic3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24iLCBwYXRpZW50X2lkLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIHNlcCA9ICJfIiwgcmVtb3ZlID0gRkFMU0UpICU+JQogIGRwbHlyOjpzZWxlY3QocGF0aWVudF9pZCwgc3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24sIHByZV9wb3N0LCBhbGxfb2Yoc2lnX2N5dG9raW5lc19yZWQkY3l0b2tpbmUpLCBhbGxfb2Yoc2lnX2N5dG9raW5lc195ZWxsb3ckY3l0b2tpbmUpLCBhbGxfb2Yoc2lnX2N5dG9raW5lc19pbnRlcnZlbnRpb24kY3l0b2tpbmUpKQoKCmN5dG9raW5lX2hlYXRtYXAgPC0gCiAgcGhlYXRtYXAoY3l0b2tpbmVfaGVhdG1hcF9kYXRhWywtYygxOjMpXSwKICAgICAgICAgICBzY2FsZSA9ICJjb2x1bW4iLCAjIHotc2NhbGluZwogICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsCiAgICAgICAgICAgY3V0cmVlX3Jvd3MgPSA2LAogICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICAgIGxhYmVsc19yb3cgPSBjeXRva2luZV9oZWF0bWFwX2RhdGEkc3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24sCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2Ygc2lnbmlmaWNhbnQgaW1tdW5vIG91dGNvbWVzIGFjcm9zcyB0aW1lcG9pbnRzIFxuYnkgcGFpcmVkIFQtdGVzdHMgXG5CZW5qYW1vbmktSG9jaGJlcmcgY29ycmVjdGVkIHAtdmFsdWVzID4gMC4wNSBcbkMxOCAoLSkiKQogIApgYGAKCiMjIEFsbCBjeXRva2luZXMKCiMjIyBaLXNjb3JlIHRyYW5zZm9ybWVkCgoKYGBge3IsIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD05LCBmaWcuYXNwPTF9CgpjeXRva2luZXNfYWxsX2hlYXRtYXBfZGF0YSA8LSBpbXB1dGVkX21ldGFfdGFibGUgJT4lCiAgdW5pdGUoInN1YmplY3RfcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uIiwgcGF0aWVudF9pZCwgcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKSAlPiUKICBkcGx5cjo6c2VsZWN0KHBhdGllbnRfaWQsIHN1YmplY3RfcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCBwcmVfcG9zdCwgYWxsX29mKGN5dG9raW5lc19sb25nJGN5dG9raW5lKSkKCgpjeXRva2luZXNfYWxsX2hlYXRtYXAgPC0gCiAgcGhlYXRtYXAoY3l0b2tpbmVzX2FsbF9oZWF0bWFwX2RhdGFbLC1jKDE6MyldLAogICAgICAgICAgIHNjYWxlID0gImNvbHVtbiIsICMgei1zY2FsaW5nCiAgICAgICAgICAgY2x1c3Rlcl9yb3dzID0gVFJVRSwKICAgICAgICAgICBjdXRyZWVfcm93cyA9IDQsCiAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EIiwKICAgICAgICAgICBsYWJlbHNfcm93ID0gY3l0b2tpbmVzX2FsbF9oZWF0bWFwX2RhdGEkc3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24sCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2YgYWxsIGN5dG9raW5lcyBmcm9tIG11bHRpcGxleCBhc3NheSIpCiAgCmBgYAoKIyMjIE5vcm1hbGl6ZWQgdG8gY29udHJvbHMKCkkgd2FudCB0byB0cnkgYSBkaWZmZXJlbnQgdGVjaG5pcXVlIGhlcmUgdG8gc2VlIGlmIHdlIGNhbiBjYXB0dXJlIHZhcmlhdGlvbiBieSBicmluZ2luZyB0aGUgdmFsdWVzIHRvIGEgdmlzdWFsbHkgbWVhbmluZ2Z1bCByYW5nZSBieSBub3JtYWxpemluZyB2YWx1ZXMgYWdhaW5zdCAiY29udHJvbHMiLiBFYWNoIHN1YmplY3Qgc2VydmVzIGFzIHRoZWlyIG93biBjb250cm9sIHByZS1pbnRlcnZlbnRpb24gKGFuZCBhbHNvIHdoZW4gdGhleSBhcmUgb24gdGhlIGxvdyBjYXJvdGVub2lkL3NveSBpbnRlcnZlbnRpb24gKFllbGxvdykpLiBUaGVzZSBkZnMgd2lsbCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgbG9nMiBmb2xkIGNoYW5nZSBkZnMgY2FsY3VsYXRlZCBmb3IgY29ycmVsYXRpb24gcGxvdHMuIEluIHRoaXMgY2FzZSwgd2Ugd2lsbCB0YWtlIGV2ZXJ5IHRyZWF0bWVudCBhbmQgZGl2aWRlIGl0IGJ5IGl0cyBjb250cm9sIChzbyBjb250cm9sIHNob3VsZCBiZSBlbmQgdXAgYmVpbmcgMCkKCgpgYGB7cn0KIyBtYWtlIGEgc3RyaW5nIG9mIG1ldGFkYXRhIGFuZCBvZiBpbW11bm8gb3V0Y29tZXMgZm9yIGVhc2UKc3RyX21ldGEgPC0gY29sbmFtZXMoaW1wdXRlZF9tZXRhX3RhYmxlWywxOjEwXSkKc3RyX2ltbXVubyA8LSBjb2xuYW1lcyhpbXB1dGVkX21ldGFfdGFibGVbLDExOjgyXSkKCiMgRXh0cmFjdCBwcmUtaW50ZXJ2ZW50aW9uIGRhdGEgYW5kIHNldCBpbW11bm8gb3V0Y29tZSBjb2x1bW5zIHRvIDAKcHJlX2RhdGFfemVyb3MgPC0gaW1wdXRlZF9tZXRhX3RhYmxlICU+JQogIGZpbHRlcihwcmVfcG9zdCA9PSAicHJlIikgJT4lCiAgbXV0YXRlKGFjcm9zcyhhbGxfb2Yoc3RyX2ltbXVubyksIH4gMCkpCgojIENvbWJpbmUgcHJlLWludGVydmVudGlvbiB6ZXJvcyB3aXRoIGxvZyBmb2xkIGNoYW5nZSB0YWJsZQpub3JtYWxpemVkX3RvX3ByZSA8LSBtZXRhX3RhYmxlX3Bvc3RfcHJlX2RpZmZlcmVuY2VzICU+JQogIG11dGF0ZShwcmVfcG9zdCA9ICJub3JtYWxpemVkX1BPU1QiKSAlPiUKICBiaW5kX3Jvd3MocHJlX2RhdGFfemVyb3MgJT4lCiAgICAgICAgICAgICAgc2VsZWN0KHN0cl9tZXRhW2MoMTo0LCA2KV0sIGFsbF9vZihzdHJfaW1tdW5vKSkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHByZV9wb3N0ID0gIm5vcm1hbGl6ZWRfUFJFIikpICU+JQogIHVuaXRlKCJwcmVfcG9zdF9pbnRlcnZlbnRpb24iLCBwcmVfcG9zdCwgaW50ZXJ2ZW50aW9uLCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKQpgYGAKCgpgYGB7ciwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwLCBmaWcuYXNwPTAuNX0KY3l0b2tpbmVzX25vcm1sb2cyRkNfaGVhdG1hcF9kYXRhIDwtIG5vcm1hbGl6ZWRfdG9fcHJlICU+JQogIHVuaXRlKCJzdWJqX3ByZV9wb3N0X2ludGVydmVudGlvbiIsIHBhdGllbnRfaWQsIHByZV9wb3N0X2ludGVydmVudGlvbiwgc2VwID0gIl8iLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGZpbHRlcihwcmVfcG9zdCA9PSAibm9ybWFsaXplZF9QT1NUIikgJT4lCiAgZHBseXI6OnNlbGVjdChzdWJqX3ByZV9wb3N0X2ludGVydmVudGlvbiwgYWxsX29mKGN5dG9raW5lc19sb25nJGN5dG9raW5lKSkKCgpjeXRva2luZXNfbm9ybXRvcHJlX2hlYXRtYXAgPC0gCiAgcGhlYXRtYXAoY3l0b2tpbmVzX25vcm1sb2cyRkNfaGVhdG1hcF9kYXRhWywtMV0sCiAgICAgICAgICAgY2x1c3Rlcl9yb3dzID0gVFJVRSwKICAgICAgICAgICBjdXRyZWVfcm93cyA9IDIsCiAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EIiwKICAgICAgICAgICBsYWJlbHNfcm93ID0gY3l0b2tpbmVzX25vcm1sb2cyRkNfaGVhdG1hcF9kYXRhJHN1YmpfcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLAogICAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShjKCIjNjdhOWNmIiwgIiNmN2Y3ZjciLCAiI2VmOGE2MiIpKSgxNiksCiAgICAgICAgICAgbWFpbiA9ICJIZWF0bWFwIG9mIGFsbCBjeXRva2luZXMgZnJvbSBtdWx0aXBsZXggYXNzYXkiKQogIApgYGAKCgpgYGB7ciwgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTEwLCBmaWcuYXNwPTAuOH0KY3l0b2tpbmVzMl9ub3JtbG9nMkZDX2hlYXRtYXBfZGF0YSA8LSBub3JtYWxpemVkX3RvX3ByZSAlPiUKICB1bml0ZSgic3Vial9wcmVfcG9zdF9pbnRlcnZlbnRpb24iLCBwYXRpZW50X2lkLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIHNlcCA9ICJfIiwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBkcGx5cjo6c2VsZWN0KHN1YmpfcHJlX3Bvc3RfaW50ZXJ2ZW50aW9uLCBhbGxfb2YoY3l0b2tpbmVzX2xvbmckY3l0b2tpbmUpKQoKCmN5dG9raW5lczJfbm9ybXRvcHJlX2hlYXRtYXAgPC0gCiAgcGhlYXRtYXAoY3l0b2tpbmVzMl9ub3JtbG9nMkZDX2hlYXRtYXBfZGF0YVssLTFdLAogICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsCiAgICAgICAgICAgY3V0cmVlX3Jvd3MgPSAyLAogICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRCIsCiAgICAgICAgICAgbGFiZWxzX3JvdyA9IGN5dG9raW5lczJfbm9ybWxvZzJGQ19oZWF0bWFwX2RhdGEkc3Vial9wcmVfcG9zdF9pbnRlcnZlbnRpb24sCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2YgYWxsIGN5dG9raW5lcyBmcm9tIG11bHRpcGxleCBhc3NheSIpCiAgCmBgYAoKIyMjIyBZZWxsb3cKCmBgYHtyfQoKeWVsbG93X25vcm1fdG9fcHJlIDwtIG5vcm1hbGl6ZWRfdG9fcHJlICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlllbGxvdyIpCmBgYAoKCmBgYHtyLCBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9OSwgZmlnLmFzcD0xfQpjeXRva2luZXNfbm9ybWxvZzJGQ195ZWxsb3dfaGVhdG1hcF9kYXRhIDwtIHllbGxvd19ub3JtX3RvX3ByZSAlPiUKICB1bml0ZSgic3ViamVjdF9wcmVfcG9zdCIsIHBhdGllbnRfaWQsIHByZV9wb3N0LCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKSAlPiUKICBkcGx5cjo6c2VsZWN0KHN1YmplY3RfcHJlX3Bvc3QsIGFsbF9vZihjeXRva2luZXNfbG9uZyRjeXRva2luZSkpCgoKY3l0b2tpbmVzX3llbGxvd19oZWF0bWFwIDwtIAogIHBoZWF0bWFwKGN5dG9raW5lc19ub3JtbG9nMkZDX3llbGxvd19oZWF0bWFwX2RhdGFbLC0xXSwKICAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFLAogICAgICAgICAgIGN1dHJlZV9yb3dzID0gMiwKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQiLAogICAgICAgICAgIGxhYmVsc19yb3cgPSBjeXRva2luZXNfbm9ybWxvZzJGQ195ZWxsb3dfaGVhdG1hcF9kYXRhJHN1YmplY3RfcHJlX3Bvc3QsCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2YgYWxsIGN5dG9raW5lcyBmcm9tIG11bHRpcGxleCBhc3NheSIpCiAgCmBgYAoKCiMjIyMgUmVkCgpgYGB7cn0KcmVkX25vcm1fdG9fcHJlIDwtIG5vcm1hbGl6ZWRfdG9fcHJlICU+JQogIGZpbHRlcihpbnRlcnZlbnRpb24gPT0gIlJlZCIpCmBgYAoKCmBgYHtyLCBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9OSwgZmlnLmFzcD0xfQpjeXRva2luZXNfbm9ybWxvZzJGQ19yZWRfaGVhdG1hcF9kYXRhIDwtIHJlZF9ub3JtX3RvX3ByZSAlPiUKICB1bml0ZSgic3ViamVjdF9wcmVfcG9zdCIsIHBhdGllbnRfaWQsIHByZV9wb3N0LCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKSAlPiUKICBkcGx5cjo6c2VsZWN0KHN1YmplY3RfcHJlX3Bvc3QsIGFsbF9vZihjeXRva2luZXNfbG9uZyRjeXRva2luZSkpCgoKY3l0b2tpbmVzX3JlZF9oZWF0bWFwIDwtIAogIHBoZWF0bWFwKGN5dG9raW5lc19ub3JtbG9nMkZDX3JlZF9oZWF0bWFwX2RhdGFbLC0xXSwKICAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFLAogICAgICAgICAgIGN1dHJlZV9yb3dzID0gMywKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQiLAogICAgICAgICAgIGxhYmVsc19yb3cgPSBjeXRva2luZXNfbm9ybWxvZzJGQ19yZWRfaGVhdG1hcF9kYXRhJHN1YmplY3RfcHJlX3Bvc3QsCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2YgYWxsIGN5dG9raW5lcyBmcm9tIG11bHRpcGxleCBhc3NheSIpCiAgCmBgYAoKIyMgU2lnbmlmaWNhbnQgY2VsbHMKYGBge3IsIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD05LCBmaWcuYXNwPTF9CmNlbGxfaGVhdG1hcF9kYXRhIDwtIGltcHV0ZWRfbWV0YV90YWJsZSAlPiUKICB1bml0ZSgic3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24iLCBwYXRpZW50X2lkLCBwcmVfcG9zdF9pbnRlcnZlbnRpb24sIHNlcCA9ICJfIiwgcmVtb3ZlID0gRkFMU0UpICU+JQogIGRwbHlyOjpzZWxlY3QocGF0aWVudF9pZCwgc3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24sIHByZV9wb3N0LCBhbGxfb2Yoc2lnX2NlbGxzX3JlZCRjZWxsX3R5cGUpLCBhbGxfb2Yoc2lnX2NlbGxzX3llbGxvdyRjZWxsX3R5cGUpLCBhbGxfb2Yoc2lnX2NlbGxzX2ludGVydmVudGlvbiRjZWxsX3R5cGUpKQoKCmNlbGxfaGVhdG1hcCA8LSAKICBwaGVhdG1hcChjZWxsX2hlYXRtYXBfZGF0YVssLWMoMTozKV0sCiAgICAgICAgICAgc2NhbGUgPSAiY29sdW1uIiwKICAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFLAogICAgICAgICAgIGN1dHJlZV9yb3dzID0gNiwKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgICBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKICAgICAgICAgICBsYWJlbHNfcm93ID0gY2VsbF9oZWF0bWFwX2RhdGEkc3ViamVjdF9wcmVfcG9zdF9pbnRlcnZlbnRpb24sCiAgICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2N2E5Y2YiLCAiI2Y3ZjdmNyIsICIjZWY4YTYyIikpKDE2KSwKICAgICAgICAgICBtYWluID0gIkhlYXRtYXAgb2Ygc2lnbmlmaWNhbnQgaW1tdW5vIG91dGNvbWVzIGFjcm9zcyB0aW1lcG9pbnRzIFxuYnkgcGFpcmVkIFQtdGVzdHMgXG5CZW5qYW1vbmktSG9jaGJlcmcgY29ycmVjdGVkIHAtdmFsdWVzID4gMC4wNSBcbkMxOCAoLSkiKQpgYGAKCgojIFN1bW1hcnkKCiogVGhlcmUgYXJlIG5vIHNlcXVlbmNlIGVmZmVjdHMgZm9yIGFueSBvZiB0aGUgb3V0Y29tZXMgCgoqIENhcm90ZW5vaWRzCiAgKiBUb3RhbCBseWNvcGVuZSBsZXZlbHMgaW5jcmVhc2Ugc2lnbmlmaWNhbnRseSBvbmx5IGFmdGVyIHRvbWF0by1zb3kgaW50ZXJ2ZW50aW9uLgoKKiBDeXRva2luZXMKICAqIE5vIGVmZmVjdHMgb2YgY2Fyb3Rlbm9pZHMgb24gY3l0b2tpbmUgbGV2ZWxzIChmcm9tIG1peGVkIGxpbmVhciBtb2RlbGluZyBhbmFseXNpcykKICAgICogT25jZSBpc29mbGF2b25lcyBhbmQgb3RoZXIgcGh5dG9jaGVtaWNhbHMgYXJlIHF1YW50aWZpZWQsIHRoZXkgd2lsbCBiZSBpbnZlc3RpZ2F0ZWQgYW5kIGl0IHdpbGwgYmUgaW50ZXJlc3RpbmcgdG8gdGVzdCBpbnRlcmFjdGlvbnMgYmV0d2VlbiB0aGUgcGh5dG9jaGVtaWNhbHMgaW4gbWl4ZWQgbW9kZWxzLgogICogSUwtNSwgR00tQ1NGLCBhbmQgSUwtMTJwNzAgaGFzIGEgc2lnbmlmaWNhbnQgcmVkdWN0aW9uIGluIGxldmVscyBvbmx5IGFmdGVyIHJlZCAodG9tYXRvLXNveSkgaW50ZXJ2ZW50aW9uCiAgKiBUaGVyZSBhcmUgbm8gc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgY3l0b2tpbmVzIHdoZW4gY29tcGFyaW5nIHBsYXNtYSBsZXZlbHMgYmV0d2VlbiBwb3N0IGludGVydmVudGlvbnMuCgoqIEltbXVuZSBjZWxsIHR5cGVzCiAgKiBBbiBOSyBjZWxsIHR5cGUgYW5kIE1EU0MgbW9ub2N5dGVzIHNpZ25pZmljYW50bHkgY2hhbmdlIChUaGUgTksgY2VsbCB0eXBlIHNpZyBkZWNyZWFzZXMsIHdoaWxlIE1EU0MgbW9ub2N5dGVzIGluY3JlYXNlKSB3aGVuIGNvbXBhcmluZyBwb3N0LVllbGxvdyBpbnRlcnZlbnRpb24gdG8gcG9zdC1SZWQuIAogICogOCBpbW11bmUgY2VsbCB0eXBlcyBzaWduaWZpY2FudGx5IGluY3JlYXNlIGFmdGVyIHllbGxvdyBpbnRlcnZlbnRpb24uCiAgKiAzIGltbXVuZSBjZWxsIHR5cGVzIChpbmNsdWRpbmcgTmFpdmUgQiBjZWxscykgc2lnbmlmaWNhbnRseSBpbmNyZWFzZSBhZnRlciByZWQgaW50ZXJ2ZW50aW9uLgogICogQ2VsbCB0eXBlICM4IChFTSBDRDgpIHNpZ25pZmljYW50bHkgaW5jcmVhc2VkIGFmdGVyIGNvbnN1bWluZyBib3RoIGp1aWNlcy4K